Boxify superslab registry, add bench profile, and document C7 hotpath experiments
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
// - API is generic over class_idx (0-7), but enabled-classes are controlled
|
||||
// by ENV so that we can start with C7 only and later extend to C5/C6.
|
||||
// - When enabled for a class:
|
||||
// tiny_page_box_refill(class_idx, out, max) will try to supply up to
|
||||
// tiny_page_box_refill(class_idx, tls, out, max) will try to supply up to
|
||||
// `max` BASE pointers using per-page freelist before falling back.
|
||||
// - When disabled for a class: the box returns 0 and caller uses legacy path.
|
||||
//
|
||||
@ -37,6 +37,7 @@
|
||||
#include "../superslab/superslab_types.h" // For TinySlabMeta, SuperSlab
|
||||
#include "../box/tiny_next_ptr_box.h" // For tiny_next_read()
|
||||
#include "../hakmem_tiny_superslab.h" // For tiny_stride_for_class(), base helpers, superslab_ref_inc/dec
|
||||
#include "../box/tiny_mem_stats_box.h" // For coarse memory accounting
|
||||
|
||||
// Superslab active counter(Release Guard Box と整合性を取るためのカウンタ更新)
|
||||
extern void ss_active_add(SuperSlab* ss, uint32_t n);
|
||||
@ -61,19 +62,28 @@ typedef struct TinyPageDesc {
|
||||
// - enabled: このクラスで Page Box を使うかどうか
|
||||
// - num_pages: 現在保持しているページ数(0〜TINY_PAGE_BOX_MAX_PAGES)
|
||||
// - pages[]: TLS が掴んだ C7/C5/C6 ページの ring(小さなバッファ)
|
||||
typedef struct TinyPageBoxState {
|
||||
typedef struct TinyPageBoxContext {
|
||||
uint8_t enabled; // 1=Page Box enabled for this class, 0=disabled
|
||||
uint8_t num_pages; // 有効な pages[] エントリ数
|
||||
uint8_t _pad[2];
|
||||
TinyPageDesc pages[TINY_PAGE_BOX_MAX_PAGES];
|
||||
} TinyPageBoxState;
|
||||
} TinyPageBoxContext;
|
||||
|
||||
// TLS/state: one TinyPageBoxState per class(per-thread Box)
|
||||
extern __thread TinyPageBoxState g_tiny_page_box_state[TINY_NUM_CLASSES];
|
||||
// TLS/state: one TinyPageBoxContext per class(per-thread Box)
|
||||
extern __thread TinyPageBoxContext g_tiny_page_box[TINY_NUM_CLASSES];
|
||||
|
||||
// One-shot init guard(per-thread)
|
||||
extern __thread int g_tiny_page_box_init_done;
|
||||
|
||||
static inline int tiny_page_box_log_enabled(void) {
|
||||
static int g_page_box_log = -1;
|
||||
if (__builtin_expect(g_page_box_log == -1, 0)) {
|
||||
const char* e = getenv("HAKMEM_TINY_PAGEBOX_LOG");
|
||||
g_page_box_log = (e && *e && *e != '0') ? 1 : 0;
|
||||
}
|
||||
return g_page_box_log;
|
||||
}
|
||||
|
||||
// Helper: parse class list from ENV and set enabled flags.
|
||||
// Default behaviour (ENV unset/empty) is to enable class 7 only.
|
||||
static inline void tiny_page_box_init_once(void) {
|
||||
@ -82,13 +92,14 @@ static inline void tiny_page_box_init_once(void) {
|
||||
}
|
||||
|
||||
// Clear all state
|
||||
memset(g_tiny_page_box_state, 0, sizeof(g_tiny_page_box_state));
|
||||
memset(g_tiny_page_box, 0, sizeof(g_tiny_page_box));
|
||||
tiny_mem_stats_add_pagebox((ssize_t)sizeof(g_tiny_page_box));
|
||||
|
||||
const char* env = getenv("HAKMEM_TINY_PAGE_BOX_CLASSES");
|
||||
if (!env || !*env) {
|
||||
// Default: enable mid-size classes (C5–C7)
|
||||
for (int c = 5; c <= 7 && c < TINY_NUM_CLASSES; c++) {
|
||||
g_tiny_page_box_state[c].enabled = 1;
|
||||
g_tiny_page_box[c].enabled = 1;
|
||||
}
|
||||
} else {
|
||||
// Parse simple comma-separated list of integers: "5,6,7"
|
||||
@ -107,7 +118,7 @@ static inline void tiny_page_box_init_once(void) {
|
||||
p++;
|
||||
}
|
||||
if (val >= 0 && val < TINY_NUM_CLASSES) {
|
||||
g_tiny_page_box_state[val].enabled = 1;
|
||||
g_tiny_page_box[val].enabled = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,7 +134,7 @@ static inline int tiny_page_box_is_enabled(int class_idx) {
|
||||
if (class_idx < 0 || class_idx >= TINY_NUM_CLASSES) {
|
||||
return 0;
|
||||
}
|
||||
return g_tiny_page_box_state[class_idx].enabled != 0;
|
||||
return g_tiny_page_box[class_idx].enabled != 0;
|
||||
}
|
||||
|
||||
// Forward declaration for TLS slab state(tiny_tls.h から参照)
|
||||
@ -133,7 +144,7 @@ extern __thread TinyTLSSlab g_tls_slabs[TINY_NUM_CLASSES];
|
||||
// ここで Page Box が利用可能なページとして登録しておくことで、
|
||||
// 後続の unified_cache_refill() から Superslab/Warm Pool に落ちる前に
|
||||
// 「既に TLS が掴んでいるページ」を優先的に使えるようにする。
|
||||
static inline void tiny_page_box_on_new_slab(TinyTLSSlab* tls)
|
||||
static inline void tiny_page_box_on_new_slab(int class_idx, TinyTLSSlab* tls)
|
||||
{
|
||||
if (!tls) {
|
||||
return;
|
||||
@ -143,6 +154,10 @@ static inline void tiny_page_box_on_new_slab(TinyTLSSlab* tls)
|
||||
tiny_page_box_init_once();
|
||||
}
|
||||
|
||||
if (class_idx < 0 || class_idx >= TINY_NUM_CLASSES) {
|
||||
return;
|
||||
}
|
||||
|
||||
SuperSlab* ss = tls->ss;
|
||||
TinySlabMeta* meta = tls->meta;
|
||||
uint8_t* base = tls->slab_base;
|
||||
@ -152,12 +167,11 @@ static inline void tiny_page_box_on_new_slab(TinyTLSSlab* tls)
|
||||
return;
|
||||
}
|
||||
|
||||
int class_idx = (int)meta->class_idx;
|
||||
if (class_idx < 0 || class_idx >= TINY_NUM_CLASSES) {
|
||||
if (meta->class_idx != (uint8_t)class_idx) {
|
||||
return;
|
||||
}
|
||||
|
||||
TinyPageBoxState* st = &g_tiny_page_box_state[class_idx];
|
||||
TinyPageBoxContext* st = &g_tiny_page_box[class_idx];
|
||||
if (!st->enabled) {
|
||||
return;
|
||||
}
|
||||
@ -200,9 +214,11 @@ static inline void tiny_page_box_on_new_slab(TinyTLSSlab* tls)
|
||||
superslab_ref_inc(ss);
|
||||
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
// Debug: Track Page Box stats per-class
|
||||
fprintf(stderr, "[PAGE_BOX_REG] class=%d num_pages=%u capacity=%u carved=%u\n",
|
||||
class_idx, st->num_pages, meta->capacity, meta->carved);
|
||||
// Debug: Track Page Box stats per-class(ENV: HAKMEM_TINY_PAGEBOX_LOG=0 で抑制)
|
||||
if (tiny_page_box_log_enabled()) {
|
||||
fprintf(stderr, "[PAGE_BOX_REG] class=%d num_pages=%u capacity=%u carved=%u\n",
|
||||
class_idx, st->num_pages, meta->capacity, meta->carved);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -219,9 +235,11 @@ static inline void tiny_page_box_on_new_slab(TinyTLSSlab* tls)
|
||||
// - Superslab/Shared Pool 呼び出し頻度を徐々に観測・調整できる。
|
||||
|
||||
static inline int tiny_page_box_refill(int class_idx,
|
||||
TinyTLSSlab* tls,
|
||||
void** out,
|
||||
int max_out)
|
||||
{
|
||||
(void)tls; // reserved for future per-TLS hints
|
||||
if (!tiny_page_box_is_enabled(class_idx)) {
|
||||
return 0;
|
||||
}
|
||||
@ -233,7 +251,7 @@ static inline int tiny_page_box_refill(int class_idx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
TinyPageBoxState* st = &g_tiny_page_box_state[class_idx];
|
||||
TinyPageBoxContext* st = &g_tiny_page_box[class_idx];
|
||||
if (st->num_pages == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user