Phase 35-39: FAST build optimization complete (+7.13% cumulative)
Phase 35-A: BENCH_MINIMAL gate function elimination (GO +4.39%) - tiny_front_v3_enabled() → constant true - tiny_metadata_cache_enabled() → constant 0 - learner_v7_enabled() → constant false - small_learner_v2_enabled() → constant false Phase 36: Policy snapshot init-once (GO +0.71%) - small_policy_v7_snapshot() version check skip in BENCH_MINIMAL - TLS cache for policy snapshot Phase 37: Standard TLS cache (NO-GO -0.07%) - TLS cache for Standard build attempted - Runtime gate overhead negates benefit Phase 38: FAST/OBSERVE/Standard workflow established - make perf_fast, make perf_observe targets - Scorecard and documentation updates Phase 39: Hot path gate constantization (GO +1.98%) - front_gate_unified_enabled() → constant 1 - alloc_dualhot_enabled() → constant 0 - g_bench_fast_front, g_v3_enabled blocks → compile-out - free_dispatch_stats_enabled() → constant false Results: - FAST v3: 56.04M ops/s (47.4% of mimalloc) - Standard: 53.50M ops/s (45.3% of mimalloc) - M1 target (50%): 5.5% remaining 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,81 @@
|
||||
# Phase 39 — FAST v3: Gate Function 定数化(BENCH_MINIMAL の固定税刈り)
|
||||
|
||||
## 目的(1行)
|
||||
|
||||
FAST build(`HAKMEM_BENCH_MINIMAL=1`)の hot path に残る **lazy-init gate**(`static int=-1` + `getenv()`)を **compile-time constant** にして、固定税を削る。
|
||||
|
||||
## 背景
|
||||
|
||||
- Phase 35-A で gate function overhead の削減が atomic prune より ROI が高いことを確認した(GO +4.39%)。
|
||||
- Phase 37 で runtime gate(lazy-init)を Standard に持ち込むと税が勝つことを確認した(NO-GO)。
|
||||
- よって **FAST でのみ**「定数化」を進めるのが安全で勝ち筋。
|
||||
|
||||
## 方針(Box Theory)
|
||||
|
||||
- “箱”は増やさず、既存 gate を **`#if HAKMEM_BENCH_MINIMAL`** で定数化する(戻せる)。
|
||||
- Standard/OBSERVE の挙動は **変更しない**。
|
||||
- link-out / 物理削除はしない(layout/LTO で符号反転する)。
|
||||
|
||||
## 対象(優先順)
|
||||
|
||||
### A) malloc hot path gate(毎 alloc)
|
||||
|
||||
ファイル: `core/front/malloc_tiny_fast.h`
|
||||
|
||||
1. `front_gate_unified_enabled()` を FAST で固定 `1`
|
||||
2. `alloc_dualhot_enabled()` を FAST で固定 `0`
|
||||
|
||||
実装方針:
|
||||
- 関数定義の内部を `#if HAKMEM_BENCH_MINIMAL` で分岐し、FAST は return constant のみ。
|
||||
- Standard/OBSERVE は現状の lazy-init を維持(A/B の自由度を残す)。
|
||||
|
||||
### B) free dispatcher 内の gate(毎 free)
|
||||
|
||||
ファイル: `core/box/hak_free_api.inc.h`
|
||||
|
||||
1. `HAKMEM_BENCH_FAST_FRONT` ブロックを FAST で固定 OFF(丸ごと compile-out でも可)
|
||||
2. `g_v3_enabled`(v3 snapshot free stub)ブロックを FAST で固定 OFF(丸ごと compile-out)
|
||||
3. `g_free_dispatch_ssot`(`getenv("HAKMEM_FREE_DISPATCH_SSOT")`)を FAST で固定 ON
|
||||
|
||||
注意:
|
||||
- `g_free_dispatch_ssot` の “正” は、現行プリセットが最適化経路を採用している前提で **ON** とする。
|
||||
- もし health/profile で SSOT=0 依存が残っていたら、まずプリセットを正に合わせる(FAST は “性能測定の正”)。
|
||||
|
||||
### C) stats gate(毎回呼ばれているなら)
|
||||
|
||||
ファイル: `core/box/free_dispatch_stats_box.h`
|
||||
|
||||
- `free_dispatch_stats_enabled()` を FAST で固定 `false`
|
||||
- `FREE_DISPATCH_STAT_INC(...)` が hot entry で呼ばれている場合、lazy-init を消せる。
|
||||
|
||||
※ 他にも hot で呼ばれている stats gate があれば同じパターンで追加(ただし “実行確認” を先に)。
|
||||
|
||||
## 実装手順(小パッチ順)
|
||||
|
||||
1. A(malloc)を先に実装(影響範囲が狭い)
|
||||
2. B(free)を実装(影響範囲が広いので health を必ず回す)
|
||||
3. C(stats)を必要に応じて追加
|
||||
|
||||
## A/B(判定)
|
||||
|
||||
### ベースライン(FAST v2)
|
||||
|
||||
- `make perf_fast`
|
||||
|
||||
### 変更後(FAST v3)
|
||||
|
||||
- `make perf_fast`
|
||||
|
||||
### 判定(build-level)
|
||||
|
||||
- **GO**: Mixed 10-run mean **+0.5% 以上**
|
||||
- **NEUTRAL**: **±0.5%**
|
||||
- **NO-GO**: **-0.5% 以下**
|
||||
|
||||
※ NO-GO の場合は即 revert(Phase 22-2 の教訓)。
|
||||
|
||||
## 可視化(最小)
|
||||
|
||||
- ベンチ結果(mean/median)を `docs/analysis/PHASE39_FAST_V3_GATE_CONSTANTIZATION_RESULTS.md` に追記
|
||||
- `docs/analysis/PERFORMANCE_TARGETS_SCORECARD.md` の FAST build 履歴を更新
|
||||
|
||||
Reference in New Issue
Block a user