Boxify superslab registry, add bench profile, and document C7 hotpath experiments

This commit is contained in:
Moe Charm (CI)
2025-12-07 03:12:27 +09:00
parent 18faa6a1c4
commit fda6cd2e67
71 changed files with 2052 additions and 286 deletions

View File

@ -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 counterRelease 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 classper-thread Box
extern __thread TinyPageBoxState g_tiny_page_box_state[TINY_NUM_CLASSES];
// TLS/state: one TinyPageBoxContext per classper-thread Box
extern __thread TinyPageBoxContext g_tiny_page_box[TINY_NUM_CLASSES];
// One-shot init guardper-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 (C5C7)
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 statetiny_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-classENV: 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;
}