# Performance Targets(mimalloc 追跡の"数値目標") 目的: 速さだけでなく **syscall / メモリ安定性 / 長時間安定性**を含めて「勝ち筋」を固定する。 ## 運用方針(Phase 38 確定) **比較基準は FAST build** を正とする: - **FAST**: 純粋な性能計測(gate function 定数化、診断カウンタ OFF) - **Standard**: 安全・互換の基準(ENV gate 有効、本線リリース用) - **OBSERVE**: 挙動観測・デバッグ(診断カウンタ ON) mimalloc との比較は **FAST build** で行う(Standard は fixed tax を含むため公平でない)。 ## Current snapshot(2025-12-16, Phase 39) 計測条件(再現の正): - Mixed: `scripts/run_mixed_10_cleanenv.sh`(`ITERS=20000000 WS=400`) - 10-run mean/median - Git: `HEAD` (Phase 39) ### hakmem Build Variants(同一バイナリレイアウト) | Build | Mean (M ops/s) | Median (M ops/s) | vs mimalloc | 備考 | |-------|----------------|------------------|-------------|------| | **FAST v3** | 56.04 | - | **47.4%** | 性能評価の正 | | Standard | 53.50 | - | 45.3% | 安全・互換基準 | | OBSERVE | TBD | - | - | 診断カウンタ ON | **FAST vs Standard delta: +4.8%**(gate function overhead の差) ### Reference allocators(別バイナリ、layout 差あり) | allocator | mean (M ops/s) | median (M ops/s) | ratio vs mimalloc (mean) | |----------|-----------------|------------------|--------------------------| | libc (same binary) | 76.257 | 76.661 | 64.5% | | system (separate) | 81.540 | 81.801 | 69.0% | | mimalloc (separate)| 118.176| 118.497 | 100% | Notes: - `system/mimalloc` は別バイナリ計測のため **layout(text size/I-cache)差分を含む reference**。 - `libc (same binary)` は `HAKMEM_FORCE_LIBC_ALLOC=1` により、同一レイアウト上での比較の目安。 - **mimalloc 比較は FAST build を使用すること**(Standard の gate overhead は hakmem 固有の税) ## 1) Speed(相対目標) 前提: **FAST build** で hakmem vs mimalloc を比較する(Standard は gate overhead を含むため不公平)。 推奨マイルストーン(Mixed 16–1024B, FAST build): | Milestone | Target | Current (FAST v3) | Status | |-----------|--------|-------------------|--------| | M1 | mimalloc の **50%** | 47.4% | 🔴 未達 | | M2 | mimalloc の **55%** | - | 🔴 未達 | | M3 | mimalloc の **60%** | - | 🔴 未達 | | M4 | mimalloc の **65–70%** | - | 🔴 未達(構造改造必要)| **現状:** FAST v3 = 56.04M ops/s = mimalloc の 47.4%(M1 未達、あと +5.5% 必要) ## 2) Syscall budget(OS churn) Tiny hot path の理想: - steady-state(warmup 後)で **mmap/munmap/madvise = 0**(または “ほぼ 0”) 目安(許容): - `mmap+munmap+madvise` 合計が **1e8 ops あたり 1 回以下**(= 1e-8 / op) Current: - `HAKMEM_SS_OS_STATS=1`(Mixed, `iters=200000000 ws=400`): - `[SS_OS_STATS] alloc=9 free=11 madvise=9 madvise_disabled=0 mmap_total=9 fallback_mmap=0 huge_alloc=0` 観測方法(どちらか): - 内部: `HAKMEM_SS_OS_STATS=1` の `[SS_OS_STATS]`(madvise/disabled 等) - 外部: `perf stat` の syscall events か `strace -c`(短い実行で回数だけ見る) ## 3) Memory stability(RSS / fragmentation) 最低条件(Mixed / ws 固定の soak): - RSS が **時間とともに単調増加しない** - 1時間の soak で RSS drift が **+5% 以内**(目安) Current: - TBD(soak のテンプレは今後スクリプト化) 推奨指標: - RSS(peak / steady) - page faults(増え続けないこと) - allocator 内部の “inuse / committed” 比(取れるなら) ## 4) Long-run stability(性能・一貫性) 最低条件: - 30–60 分の soak で ops/s が **-5% 以上落ちない** - CV(変動係数)が **~1–2%** に収まる(現状の運用と整合) Current: - Mixed 10-run(上の snapshot): CV ≈ 0.91%(mean 54.646M / min 53.608M / max 55.311M) ## 5) 判定ルール(運用) - runtime 変更(ENVのみ): GO 閾値 +1.0%(Mixed 10-run mean) - build-level 変更(compile-out 系): GO 閾値 +0.5%(layout の揺れを考慮) ## 6) Build Variants(FAST / Standard / OBSERVE)— Phase 38 運用 ### 3種類のビルド | Build | Binary | 目的 | 特徴 | |-------|--------|------|------| | **FAST** | `bench_random_mixed_hakmem_minimal` | 純粋な性能計測 | gate function 定数化、診断 OFF | | **Standard** | `bench_random_mixed_hakmem` | 安全・互換基準 | ENV gate 有効、本線リリース用 | | **OBSERVE** | `bench_random_mixed_hakmem_observe` | 挙動観測 | 診断カウンタ ON、perf 分析用 | ### 運用ルール(Phase 38 確定) 1. **性能評価は FAST build で行う**(mimalloc 比較の正) 2. **Standard は安全基準**(gate overhead は許容、本線機能の互換性優先) 3. **OBSERVE はデバッグ用**(性能評価には使わない、診断出力あり) ### FAST build 履歴 | Version | Mean (ops/s) | Delta | 変更内容 | |---------|--------------|-------|----------| | FAST v1 | 54,557,938 | baseline | Phase 35-A: gate function 定数化 | | FAST v2 | 54,943,734 | +0.71% | Phase 36: policy snapshot init-once | | **FAST v3** | 56,040,000 | +1.98% | Phase 39: hot path gate 定数化 | **FAST v3 で定数化されたもの:** - `tiny_front_v3_enabled()` → 常に `true` - `tiny_metadata_cache_enabled()` → 常に `0` - `small_policy_v7_snapshot()` → version check スキップ、init-once TLS cache - `learner_v7_enabled()` → 常に `false` - `small_learner_v2_enabled()` → 常に `false` - `front_gate_unified_enabled()` → 常に `1`(Phase 39) - `alloc_dualhot_enabled()` → 常に `0`(Phase 39) - `g_bench_fast_front` block → compile-out(Phase 39) - `g_v3_enabled` block → compile-out(Phase 39) - `free_dispatch_stats_enabled()` → 常に `false`(Phase 39) ### 使い方(Phase 38 ワークフロー) **推奨: 自動化ターゲットを使用** ```bash # FAST 10-run 性能評価(mimalloc 比較の正) make perf_fast # OBSERVE health check(syscall/診断確認) make perf_observe # 両方実行 make perf_all ``` **手動実行(個別制御が必要な場合)** ```bash # FAST build のみビルド make bench_random_mixed_hakmem_minimal # Standard build のみビルド make bench_random_mixed_hakmem # OBSERVE build のみビルド make bench_random_mixed_hakmem_observe # 10-run 実行(任意の binary で) scripts/run_mixed_10_cleanenv.sh ``` ### Phase 37 教訓(Standard 最適化の限界) Standard build を速くする試み(TLS cache)は NO-GO (-0.07%): - Runtime gate (lazy-init) は必ず overhead を持つ - Compile-time constant (BENCH_MINIMAL) が唯一の解 - **結論:** Standard は安全基準として維持、性能は FAST で評価 ### Phase 39 実施済み(FAST v3) 以下の gate function は Phase 39 で定数化済み: **malloc path(実施済み):** | Gate | File | FAST v3 値 | Status | |------|------|-----------|--------| | `front_gate_unified_enabled()` | malloc_tiny_fast.h | 固定 1 | ✅ GO | | `alloc_dualhot_enabled()` | malloc_tiny_fast.h | 固定 0 | ✅ GO | **free path(実施済み):** | Gate | File | FAST v3 値 | Status | |------|------|-----------|--------| | `g_bench_fast_front` | hak_free_api.inc.h | compile-out | ✅ GO | | `g_v3_enabled` | hak_free_api.inc.h | compile-out | ✅ GO | | `g_free_dispatch_ssot` | hak_free_api.inc.h | lazy-init 維持 | 保留 | **stats(実施済み):** | Gate | File | FAST v3 値 | Status | |------|------|-----------|--------| | `free_dispatch_stats_enabled()` | free_dispatch_stats_box.h | 固定 false | ✅ GO | **Phase 39 結果:** +1.98%(GO)