Files
hakmem/core/box/hak_kpi_util.inc.h
Moe Charm (CI) acc64f2438 Phase ML1: Pool v1 memset 89.73% overhead 軽量化 (+15.34% improvement)
## 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>
2025-12-10 09:08:18 +09:00

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