summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2019-03-07 19:14:31 (GMT)
committerDave Watson <davejwatson@fb.com>2019-05-08 20:15:19 (GMT)
commit56797512083fe1457163170dfa44ee5ec12abe5f (patch)
treeea58aac5541f17492106fd696079fb6aa22a0db5
parentb62d126df894dac00772eb5f3d170a1c1d3d1614 (diff)
downloadjemalloc-56797512083fe1457163170dfa44ee5ec12abe5f.zip
jemalloc-56797512083fe1457163170dfa44ee5ec12abe5f.tar.gz
jemalloc-56797512083fe1457163170dfa44ee5ec12abe5f.tar.bz2
Remove best fit
This option saves a few CPU cycles, but potentially adds a lot of fragmentation - so much so that there are workarounds like max_active. Instead, let's just drop it entirely. It only made a difference in one service I tested (.3% cpu regression), while many services saw a memory win (also small, less than 1% mem P99)
-rw-r--r--src/extent.c40
1 files changed, 8 insertions, 32 deletions
diff --git a/src/extent.c b/src/extent.c
index c8d1dd5..e83d9c8 100644
--- a/src/extent.c
+++ b/src/extent.c
@@ -441,30 +441,6 @@ extents_fit_alignment(extents_t *extents, size_t min_size, size_t max_size,
return NULL;
}
-/* Do any-best-fit extent selection, i.e. select any extent that best fits. */
-static extent_t *
-extents_best_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
- size_t size) {
- pszind_t pind = sz_psz2ind(extent_size_quantize_ceil(size));
- pszind_t i = (pszind_t)bitmap_ffu(extents->bitmap, &extents_bitmap_info,
- (size_t)pind);
- if (i < SC_NPSIZES + 1) {
- /*
- * In order to reduce fragmentation, avoid reusing and splitting
- * large extents for much smaller sizes.
- */
- if ((sz_pind2sz(i) >> opt_lg_extent_max_active_fit) > size) {
- return NULL;
- }
- assert(!extent_heap_empty(&extents->heaps[i]));
- extent_t *extent = extent_heap_first(&extents->heaps[i]);
- assert(extent_size_get(extent) >= size);
- return extent;
- }
-
- return NULL;
-}
-
/*
* Do first-fit extent selection, i.e. select the oldest/lowest extent that is
* large enough.
@@ -487,12 +463,15 @@ extents_first_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
/*
* In order to reduce fragmentation, avoid reusing and splitting
* large extents for much smaller sizes.
+ *
+ * Only do check for dirty extents (delay_coalesce).
*/
- if ((sz_pind2sz(i) >> opt_lg_extent_max_active_fit) > size) {
+ if (extents->delay_coalesce &&
+ (sz_pind2sz(i) >> opt_lg_extent_max_active_fit) > size) {
size_ok = false;
}
if (size_ok &&
- (ret == NULL || extent_snad_comp(extent, ret) < 0)) {
+ (ret == NULL || extent_snad_comp(extent, ret) < 0)) {
ret = extent;
}
if (i == SC_NPSIZES) {
@@ -505,10 +484,8 @@ extents_first_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
}
/*
- * Do {best,first}-fit extent selection, where the selection policy choice is
- * based on extents->delay_coalesce. Best-fit selection requires less
- * searching, but its layout policy is less stable and may cause higher virtual
- * memory fragmentation as a side effect.
+ * Do first-fit extent selection, where the selection policy choice is
+ * based on extents->delay_coalesce.
*/
static extent_t *
extents_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
@@ -521,8 +498,7 @@ extents_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
return NULL;
}
- extent_t *extent = extents->delay_coalesce ?
- extents_best_fit_locked(tsdn, arena, extents, max_size) :
+ extent_t *extent =
extents_first_fit_locked(tsdn, arena, extents, max_size);
if (alignment > PAGE && extent == NULL) {