97 lines
3.0 KiB
C
97 lines
3.0 KiB
C
|
|
// 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 <stdint.h>
|
|||
|
|
|
|||
|
|
#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
|