Commit 5d820ea6 authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by facebook-github-bot-0

Make goodMallocSize always use nallocx

Summary: `goodMallocSize` is used extensively in `folly` data structures,
especially for containers optimized for small contents, such as
`fbstring` and `small_vector`.

However, it makes the design decision to align the allocation size to
a x86 cache line, forcing a minimum allocation size of `64` bytes,
despite jemalloc can provide smaller size classes (8, 16, 32,
48). This causes a large discontinuity between small contents that can
be inlined and heap-allocated contents:

- For `fbstring`, a string of 23 bytes (including terminator) occupies
  24 bytes (`sizeof(fbstring)`), a string of 24 bytes occupies 24 + 64
  + allocation overhead when it could be 24 + 32 + allocation
  overhead. The waste is more than 50%.

- For `small_vector<uint32_t, 1, uint32_t>`, for instance, a vector
  with 1 element occupies 12 bytes, a vector with 2 elements occupies
  12 + 64 + allocation overhead when it could be 12 + 8 + allocation
  overhead. The waste is more than 250%.

With this diff we just trust jemalloc and always use `nallocx`. If a
data structure need cache-line alignment it should be implemented at
its level.

Reviewed By: elsteveogrande

Differential Revision: D2688156

fb-gh-sync-id: 46548d4a91952e7c673d4f0997c4c067e03c190d
parent 1f4a8221
......@@ -176,33 +176,13 @@ inline bool usingJEMalloc() noexcept {
return result;
}
/**
* For jemalloc's size classes, see
* http://www.canonware.com/download/jemalloc/jemalloc-latest/doc/jemalloc.html
*/
inline size_t goodMallocSize(size_t minSize) noexcept {
if (!usingJEMalloc()) {
// Not using jemalloc - no smarts
return minSize;
}
size_t goodSize;
if (minSize <= 64) {
// Choose smallest allocation to be 64 bytes - no tripping over
// cache line boundaries, and small string optimization takes care
// of short strings anyway.
goodSize = 64;
} else if (minSize <= 512) {
// Round up to the next multiple of 64; we don't want to trip over
// cache line boundaries.
goodSize = (minSize + 63) & ~size_t(63);
} else {
// Boundaries between size classes depend on numerious factors, some of
// which can even be modified at run-time. Determine the good allocation
// size by calling nallocx() directly.
goodSize = nallocx(minSize, 0);
}
assert(nallocx(goodSize, 0) == goodSize);
return goodSize;
return nallocx(minSize, 0);
}
// We always request "good" sizes for allocation, so jemalloc can
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment