mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-06-03 18:54:16 +03:00
Use SEC in PAC to reduce lock contention on the ecaches
Add a small extent cache in front of the PAC ecaches. Allocs and dallocs that fit are served from per-shard SEC bins without taking the ecache mutex; overflow falls through to the backing ecaches, including ecache_pinned for pinned extents. The feature is gated behind experimental_pac_sec_nshards (default 0, disabled). To support independent HPA and PAC SEC instances, sec_alloc/sec_dalloc/sec_fill take an explicit shard argument, with HPA and PAC using separate TSD shard slots.
This commit is contained in:
parent
11b99d7a21
commit
6b13adf375
19 changed files with 680 additions and 59 deletions
|
|
@ -22,6 +22,7 @@ extern bool opt_confirm_conf;
|
|||
extern bool opt_hpa;
|
||||
extern hpa_shard_opts_t opt_hpa_opts;
|
||||
extern sec_opts_t opt_hpa_sec_opts;
|
||||
extern sec_opts_t opt_pac_sec_opts;
|
||||
|
||||
extern const char *opt_junk;
|
||||
extern bool opt_junk_alloc;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ typedef enum {
|
|||
OP(tcache_list) \
|
||||
OP(hpa_shard) \
|
||||
OP(hpa_shard_grow) \
|
||||
OP(hpa_sec)
|
||||
OP(hpa_sec) \
|
||||
OP(pac_sec)
|
||||
|
||||
typedef enum {
|
||||
#define OP(mtx) arena_prof_mutex_##mtx,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "jemalloc/internal/edata_cache.h"
|
||||
#include "jemalloc/internal/exp_grow.h"
|
||||
#include "jemalloc/internal/lockedint.h"
|
||||
#include "jemalloc/internal/sec.h"
|
||||
#include "jemalloc/internal/tsd_types.h"
|
||||
#include "san_bump.h"
|
||||
|
||||
|
|
@ -84,12 +85,21 @@ struct pac_stats_s {
|
|||
|
||||
/* VM space had to be leaked (undocumented). Normally 0. */
|
||||
atomic_zu_t abandoned_vm;
|
||||
|
||||
/* PAC SEC stats. Derived. */
|
||||
sec_stats_t pac_sec_stats;
|
||||
};
|
||||
|
||||
typedef struct pac_s pac_t;
|
||||
struct pac_s {
|
||||
/* Small extent cache in front of PAC ecaches to reduce contention. */
|
||||
sec_t sec;
|
||||
/* 0 disables PAC SEC; otherwise max size SEC will cache. */
|
||||
atomic_zu_t sec_max_alloc;
|
||||
|
||||
/* True once pinned memory has been seen. */
|
||||
atomic_b_t has_pinned;
|
||||
|
||||
/*
|
||||
* Collections of extents that were previously allocated. These are
|
||||
* used when allocating extents, in an attempt to re-use address space.
|
||||
|
|
@ -237,4 +247,6 @@ ssize_t pac_decay_ms_get(pac_t *pac, extent_state_t state);
|
|||
void pac_reset(tsdn_t *tsdn, pac_t *pac);
|
||||
void pac_destroy(tsdn_t *tsdn, pac_t *pac);
|
||||
|
||||
void pac_sec_flush(tsdn_t *tsdn, pac_t *pac);
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_PAC_H */
|
||||
|
|
|
|||
|
|
@ -111,10 +111,17 @@ sec_size_supported(sec_t *sec, size_t size) {
|
|||
void sec_calc_nallocs_for_size(
|
||||
sec_t *sec, size_t size, size_t *min_nallocs, size_t *max_nallocs);
|
||||
|
||||
/*
|
||||
* Lazily picks (and caches in *idxp) a shard for the calling thread. Different
|
||||
* SEC instances pass independent per-thread uint8_t slots, initialized to
|
||||
* (uint8_t)-1.
|
||||
*/
|
||||
uint8_t sec_shard_pick(tsd_t *tsd, sec_t *sec, uint8_t *idxp);
|
||||
|
||||
/* If sec does not have extent available, it will return NULL. */
|
||||
edata_t *sec_alloc(tsdn_t *tsdn, sec_t *sec, size_t size);
|
||||
edata_t *sec_alloc(tsdn_t *tsdn, sec_t *sec, size_t size, uint8_t shard);
|
||||
void sec_fill(tsdn_t *tsdn, sec_t *sec, size_t size,
|
||||
edata_list_active_t *result, size_t nallocs);
|
||||
edata_list_active_t *result, size_t nallocs, uint8_t shard);
|
||||
|
||||
/*
|
||||
* Upon return dalloc_list may be empty if edata is consumed by sec or non-empty
|
||||
|
|
@ -124,7 +131,8 @@ void sec_fill(tsdn_t *tsdn, sec_t *sec, size_t size,
|
|||
* considered "hot" and preserved in the cache, while "colder" ones are
|
||||
* returned).
|
||||
*/
|
||||
void sec_dalloc(tsdn_t *tsdn, sec_t *sec, edata_list_active_t *dalloc_list);
|
||||
void sec_dalloc(tsdn_t *tsdn, sec_t *sec, edata_list_active_t *dalloc_list,
|
||||
uint8_t shard);
|
||||
|
||||
bool sec_init(tsdn_t *tsdn, sec_t *sec, base_t *base, const sec_opts_t *opts);
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ typedef void (*test_callback_t)(int *);
|
|||
O(arena, arena_t *, arena_t *) \
|
||||
O(arena_decay_ticker, ticker_geom_t, ticker_geom_t) \
|
||||
O(sec_shard, uint8_t, uint8_t) \
|
||||
O(pac_sec_shard, uint8_t, uint8_t) \
|
||||
O(binshards, tsd_binshards_t, tsd_binshards_t) \
|
||||
O(peak, peak_t, peak_t) \
|
||||
O(tcache_slow, tcache_slow_t, tcache_slow_t) \
|
||||
|
|
@ -95,6 +96,7 @@ typedef void (*test_callback_t)(int *);
|
|||
/* arena */ NULL, /* arena_decay_ticker */ \
|
||||
TICKER_GEOM_INIT(ARENA_DECAY_NTICKS_PER_UPDATE), \
|
||||
/* sec_shard */ (uint8_t) - 1, \
|
||||
/* pac_sec_shard */ (uint8_t) - 1, \
|
||||
/* binshards */ TSD_BINSHARDS_ZERO_INITIALIZER, \
|
||||
/* peak */ PEAK_INITIALIZER, /* tcache_slow */ \
|
||||
TCACHE_SLOW_ZERO_INITIALIZER, \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue