From 205ba7b223a698c1cfe75759ea29e0bc354a8596 Mon Sep 17 00:00:00 2001 From: Guangli Dai Date: Fri, 31 Jan 2025 14:07:05 -0800 Subject: [PATCH] Prepare tcache for size to grow by PAGE over GROUP*PAGE To prepare for the upcoming changes where size class grows by PAGE when larger than NGROUP * PAGE, disable the tcache when it is larger than 2 * NGROUP * PAGE. The threshold for tcache is set higher to prevent perf regression as much as possible while usizes between NGROUP * PAGE and 2 * NGROUP * PAGE happen to grow by PAGE. --- include/jemalloc/internal/sc.h | 18 ++++++++++++++++++ include/jemalloc/internal/tcache_types.h | 6 +++++- src/jemalloc.c | 3 +++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/jemalloc/internal/sc.h b/include/jemalloc/internal/sc.h index 770835cc..098e47b7 100644 --- a/include/jemalloc/internal/sc.h +++ b/include/jemalloc/internal/sc.h @@ -286,6 +286,24 @@ # endif #endif +/* + * When config_limit_usize_gap is enabled, the gaps between two contiguous + * size classes should not exceed PAGE. This means there should be no concept + * of size classes for sizes > SC_SMALL_MAXCLASS (or >= SC_LARGE_MINCLASS). + * However, between SC_LARGE_MINCLASS (SC_NGROUP * PAGE) and + * 2 * SC_NGROUP * PAGE, the size class also happens to be aligned with PAGE. + * Since tcache relies on size classes to work and it greatly increases the + * perf of allocs & deallocs, we extend the existence of size class to + * 2 * SC_NGROUP * PAGE ONLY for the tcache module. This means for all other + * modules, there is no size class for sizes >= SC_LARGE_MINCLASS. Yet for + * tcache, the threshold is moved up to 2 * SC_NGROUP * PAGE, which is + * USIZE_GROW_SLOW_THRESHOLD defined below. With the default SC_NGROUP being + * 2, and PAGE being 4KB, the threshold for tcache (USIZE_GROW_SLOW_THRESHOLD) + * is 32KB. + */ +#define LG_USIZE_GROW_SLOW_THRESHOLD (SC_LG_NGROUP + LG_PAGE + 1) +#define USIZE_GROW_SLOW_THRESHOLD (1U << LG_USIZE_GROW_SLOW_THRESHOLD) + #define SC_SLAB_MAXREGS (1U << SC_LG_SLAB_MAXREGS) typedef struct sc_s sc_t; diff --git a/include/jemalloc/internal/tcache_types.h b/include/jemalloc/internal/tcache_types.h index eebad79f..f13ff748 100644 --- a/include/jemalloc/internal/tcache_types.h +++ b/include/jemalloc/internal/tcache_types.h @@ -19,7 +19,11 @@ typedef struct tcaches_s tcaches_t; /* NOLINTNEXTLINE(performance-no-int-to-ptr) */ #define TCACHES_ELM_NEED_REINIT ((tcache_t *)(uintptr_t)1) -#define TCACHE_LG_MAXCLASS_LIMIT 23 /* tcache_max = 8M */ +#ifdef LIMIT_USIZE_GAP + #define TCACHE_LG_MAXCLASS_LIMIT LG_USIZE_GROW_SLOW_THRESHOLD +#else + #define TCACHE_LG_MAXCLASS_LIMIT 23 /* tcache_max = 8M */ +#endif #define TCACHE_MAXCLASS_LIMIT ((size_t)1 << TCACHE_LG_MAXCLASS_LIMIT) #define TCACHE_NBINS_MAX (SC_NBINS + SC_NGROUP * \ (TCACHE_LG_MAXCLASS_LIMIT - SC_LG_LARGE_MINCLASS) + 1) diff --git a/src/jemalloc.c b/src/jemalloc.c index e313de36..01c770aa 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -2201,6 +2201,9 @@ static bool malloc_init_hard(void) { tsd_t *tsd; + if (config_limit_usize_gap) { + assert(TCACHE_MAXCLASS_LIMIT <= USIZE_GROW_SLOW_THRESHOLD); + } #if defined(_WIN32) && _WIN32_WINNT < 0x0600 _init_init_lock(); #endif