Use first fit layout policy instead of best fit.
For extents which do not delay coalescing, use first fit layout policy rather than first-best fit layout policy. This packs extents toward older virtual memory mappings, but at the cost of higher search overhead in the common case. This resolves #711.
This commit is contained in:
parent
bbc16a50f9
commit
a832ebaee9
54
src/extent.c
54
src/extent.c
@ -256,21 +256,13 @@ extents_remove_locked(tsdn_t *tsdn, extents_t *extents, extent_t *extent,
|
|||||||
cur_extents_npages - (size >> LG_PAGE), ATOMIC_RELAXED);
|
cur_extents_npages - (size >> LG_PAGE), ATOMIC_RELAXED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Do any-best-fit extent selection, i.e. select any extent that best fits. */
|
||||||
* Do {first,any}-best-fit extent selection, i.e. select the oldest/lowest or
|
|
||||||
* any extent that best fits, where {first,any} corresponds to
|
|
||||||
* extents->delay_coalesce={false,true}.
|
|
||||||
*/
|
|
||||||
static extent_t *
|
static extent_t *
|
||||||
extents_best_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
|
extents_best_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
|
||||||
size_t size) {
|
size_t size) {
|
||||||
malloc_mutex_assert_owner(tsdn, &extents->mtx);
|
|
||||||
|
|
||||||
pszind_t pind = psz2ind(extent_size_quantize_ceil(size));
|
pszind_t pind = psz2ind(extent_size_quantize_ceil(size));
|
||||||
for (pszind_t i = pind; i < NPSIZES+1; i++) {
|
for (pszind_t i = pind; i < NPSIZES+1; i++) {
|
||||||
extent_t *extent = extents->delay_coalesce ?
|
extent_t *extent = extent_heap_any(&extents->heaps[i]);
|
||||||
extent_heap_any(&extents->heaps[i]) :
|
|
||||||
extent_heap_first(&extents->heaps[i]);
|
|
||||||
if (extent != NULL) {
|
if (extent != NULL) {
|
||||||
assert(extent_size_get(extent) >= size);
|
assert(extent_size_get(extent) >= size);
|
||||||
return extent;
|
return extent;
|
||||||
@ -280,6 +272,45 @@ extents_best_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do first-fit extent selection, i.e. select the oldest/lowest extent that is
|
||||||
|
* large enough.
|
||||||
|
*/
|
||||||
|
static extent_t *
|
||||||
|
extents_first_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
|
||||||
|
size_t size) {
|
||||||
|
extent_t *ret = NULL;
|
||||||
|
|
||||||
|
pszind_t pind = psz2ind(extent_size_quantize_ceil(size));
|
||||||
|
for (pszind_t i = pind; i < NPSIZES+1; i++) {
|
||||||
|
extent_t *extent = extent_heap_first(&extents->heaps[i]);
|
||||||
|
if (extent != NULL) {
|
||||||
|
assert(extent_size_get(extent) >= size);
|
||||||
|
if (ret == NULL || extent_snad_comp(extent, ret) < 0) {
|
||||||
|
ret = extent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
static extent_t *
|
||||||
|
extents_fit_locked(tsdn_t *tsdn, arena_t *arena, extents_t *extents,
|
||||||
|
size_t size) {
|
||||||
|
malloc_mutex_assert_owner(tsdn, &extents->mtx);
|
||||||
|
|
||||||
|
return extents->delay_coalesce ? extents_best_fit_locked(tsdn, arena,
|
||||||
|
extents, size) : extents_first_fit_locked(tsdn, arena, extents,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
extent_try_delayed_coalesce(tsdn_t *tsdn, arena_t *arena,
|
extent_try_delayed_coalesce(tsdn_t *tsdn, arena_t *arena,
|
||||||
extent_hooks_t **r_extent_hooks, rtree_ctx_t *rtree_ctx, extents_t *extents,
|
extent_hooks_t **r_extent_hooks, rtree_ctx_t *rtree_ctx, extents_t *extents,
|
||||||
@ -675,8 +706,7 @@ extent_recycle_extract(tsdn_t *tsdn, arena_t *arena,
|
|||||||
extent = NULL;
|
extent = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
extent = extents_best_fit_locked(tsdn, arena, extents,
|
extent = extents_fit_locked(tsdn, arena, extents, alloc_size);
|
||||||
alloc_size);
|
|
||||||
}
|
}
|
||||||
if (extent == NULL) {
|
if (extent == NULL) {
|
||||||
if (!locked) {
|
if (!locked) {
|
||||||
|
Loading…
Reference in New Issue
Block a user