// pagefault_telemetry_box.h - Box PageFaultTelemetry: Tiny page-touch visualization // Purpose: // - Approximate「何枚のページをどれだけ触ったか」をクラス別に計測する箱。 // - Tiny フロントエンド側からのみ呼び出し、Superslab/カーネル側の挙動は変更しない。 // // Design: // - 4KB ページ単位でアドレスを正規化し、簡易 Bloom/ビットセットにハッシュ。 // - 1 クラスあたり 1024bit (= 16 x uint64_t) を用意し、popcount で「近似ページ枚数」を算出。 // - 衝突は起こり得るが「下限近似値」として十分。目的は傾向把握。 // // ENV Control: // - HAKMEM_TINY_PAGEFAULT_TELEMETRY=1 … 計測有効化 // - HAKMEM_TINY_PAGEFAULT_DUMP=1 … 終了時に stderr へ 1 回だけダンプ #ifndef HAK_BOX_PAGEFAULT_TELEMETRY_H #define HAK_BOX_PAGEFAULT_TELEMETRY_H #include #ifdef __cplusplus extern "C" { #endif // Tiny クラス数(既存定義が無ければ 8 とみなす) #ifndef TINY_NUM_CLASSES #define TINY_NUM_CLASSES 8 #endif // ドメインバケット定義: // 0..7 : Tiny C0..C7 // 8 : Mid Pool (hak_pool_*) // 9 : L25 Pool (hak_l25_pool_*) // 10 : Shared SuperSlab meta / backing // 11 : 予備 enum { PF_BUCKET_TINY_BASE = 0, PF_BUCKET_TINY_LIMIT = TINY_NUM_CLASSES, PF_BUCKET_MID = TINY_NUM_CLASSES, PF_BUCKET_L25 = TINY_NUM_CLASSES + 1, PF_BUCKET_SS_META = TINY_NUM_CLASSES + 2, PF_BUCKET_RESERVED = TINY_NUM_CLASSES + 3, PF_BUCKET_MAX = TINY_NUM_CLASSES + 4 }; // ビットセット本体(1 バケットあたり 1024bit) extern __thread uint64_t g_pf_bloom[PF_BUCKET_MAX][16]; // タッチ総数(ページ単位ではなく「呼び出し回数」) extern __thread uint64_t g_pf_touch[PF_BUCKET_MAX]; // ENV による有効/無効判定(キャッシュ付き) int pagefault_telemetry_enabled(void); // 集計・ダンプ(ENV HAKMEM_TINY_PAGEFAULT_DUMP=1 のときだけ出力) void pagefault_telemetry_dump(void); // ---------------------------------------------------------------------------- // Inline helper: ページタッチ記録 // ---------------------------------------------------------------------------- static inline void pagefault_telemetry_touch(int cls, const void* ptr) { #if HAKMEM_DEBUG_COUNTERS if (!pagefault_telemetry_enabled()) { return; } if (cls < 0 || cls >= PF_BUCKET_MAX) { return; } // 4KB ページに正規化 uintptr_t addr = (uintptr_t)ptr; uintptr_t page = addr >> 12; // 1024 エントリのビットセットにハッシュ uint32_t idx = (uint32_t)(page & 1023u); uint32_t word = idx >> 6; uint32_t bit = idx & 63u; uint64_t mask = (uint64_t)1u << bit; uint64_t old = g_pf_bloom[cls][word]; if (!(old & mask)) { g_pf_bloom[cls][word] = old | mask; } g_pf_touch[cls]++; #else (void)cls; (void)ptr; #endif } #ifdef __cplusplus } #endif #endif // HAK_BOX_PAGEFAULT_TELEMETRY_H