## Summary - ChatGPT により bench_profile.h の setenv segfault を修正(RTLD_NEXT 経由に切り替え) - core/box/pool_zero_mode_box.h 新設:ENV キャッシュ経由で ZERO_MODE を統一管理 - core/hakmem_pool.c で zero mode に応じた memset 制御(FULL/header/off) - A/B テスト結果:ZERO_MODE=header で +15.34% improvement(1M iterations, C6-heavy) ## Files Modified - core/box/pool_api.inc.h: pool_zero_mode_box.h include - core/bench_profile.h: glibc setenv → malloc+putenv(segfault 回避) - core/hakmem_pool.c: zero mode 参照・制御ロジック - core/box/pool_zero_mode_box.h (新設): enum/getter - CURRENT_TASK.md: Phase ML1 結果記載 ## Test Results | Iterations | ZERO_MODE=full | ZERO_MODE=header | Improvement | |-----------|----------------|-----------------|------------| | 10K | 3.06 M ops/s | 3.17 M ops/s | +3.65% | | 1M | 23.71 M ops/s | 27.34 M ops/s | **+15.34%** | 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
76 lines
2.7 KiB
C
76 lines
2.7 KiB
C
// hak_kpi_util.inc.h — KPI measurement helpers (Linux / non-Linux)
|
|
#ifndef HAK_KPI_UTIL_INC_H
|
|
#define HAK_KPI_UTIL_INC_H
|
|
|
|
#ifdef __linux__
|
|
// Latency histogram (simple buckets for P50/P95/P99)
|
|
#define LATENCY_BUCKETS 100
|
|
static uint64_t g_latency_histogram[LATENCY_BUCKETS];
|
|
static uint64_t g_latency_samples = 0;
|
|
|
|
// Baseline page faults (at init)
|
|
static uint64_t g_baseline_soft_pf = 0;
|
|
static uint64_t g_baseline_hard_pf = 0;
|
|
static uint64_t g_baseline_rss_kb = 0;
|
|
|
|
// Get page faults from /proc/self/stat
|
|
static void get_page_faults(uint64_t* soft_pf, uint64_t* hard_pf) {
|
|
FILE* f = fopen("/proc/self/stat", "r");
|
|
if (!f) { *soft_pf = 0; *hard_pf = 0; return; }
|
|
unsigned long minflt = 0, majflt = 0;
|
|
unsigned long dummy; char comm[256], state;
|
|
int stat_ret = fscanf(f, "%lu %s %c %lu %lu %lu %lu %lu %lu %lu %lu %lu",
|
|
&dummy, comm, &state, &dummy, &dummy, &dummy, &dummy, &dummy,
|
|
&dummy, &minflt, &dummy, &majflt);
|
|
(void)stat_ret;
|
|
fclose(f);
|
|
*soft_pf = minflt; *hard_pf = majflt;
|
|
}
|
|
|
|
// Get RSS from /proc/self/statm (in KB)
|
|
static uint64_t get_rss_kb(void) {
|
|
FILE* f = fopen("/proc/self/statm", "r");
|
|
if (!f) return 0;
|
|
unsigned long size, resident;
|
|
int statm_ret = fscanf(f, "%lu %lu", &size, &resident);
|
|
(void)statm_ret;
|
|
fclose(f);
|
|
long page_size = sysconf(_SC_PAGESIZE);
|
|
return (resident * page_size) / 1024; // Convert to KB
|
|
}
|
|
|
|
static uint64_t calculate_percentile(double percentile) {
|
|
if (g_latency_samples == 0) return 0;
|
|
uint64_t target = (uint64_t)(g_latency_samples * percentile);
|
|
uint64_t cumulative = 0;
|
|
for (size_t i = 0; i < LATENCY_BUCKETS; i++) {
|
|
cumulative += g_latency_histogram[i];
|
|
if (cumulative >= target) return i * 10; // Return bucket midpoint (ns)
|
|
}
|
|
return (LATENCY_BUCKETS - 1) * 10;
|
|
}
|
|
|
|
// Implement hak_get_kpi()
|
|
void hak_get_kpi(hak_kpi_t* out) {
|
|
memset(out, 0, sizeof(hak_kpi_t));
|
|
// Latency (from histogram)
|
|
out->p50_alloc_ns = calculate_percentile(0.50);
|
|
out->p95_alloc_ns = calculate_percentile(0.95);
|
|
out->p99_alloc_ns = calculate_percentile(0.99);
|
|
// Page Faults (delta from baseline)
|
|
uint64_t soft_pf, hard_pf; get_page_faults(&soft_pf, &hard_pf);
|
|
out->soft_page_faults = soft_pf - g_baseline_soft_pf;
|
|
out->hard_page_faults = hard_pf - g_baseline_hard_pf;
|
|
// RSS (delta from baseline, in MB)
|
|
uint64_t rss_kb = get_rss_kb();
|
|
int64_t rss_delta_kb = (int64_t)rss_kb - (int64_t)g_baseline_rss_kb;
|
|
out->rss_delta_mb = rss_delta_kb / 1024;
|
|
}
|
|
|
|
#else
|
|
// Non-Linux: stub implementation
|
|
void hak_get_kpi(hak_kpi_t* out) { memset(out, 0, sizeof(hak_kpi_t)); }
|
|
#endif
|
|
|
|
#endif // HAK_KPI_UTIL_INC_H
|