Phase v7-5a: Hot path stats removal (C6 v7 極限最適化)

- Remove per-page stats from hot path (alloc_count, free_count, live_current)
- Add ENV-gated global atomic stats (HAKMEM_V7_HOT_STATS)
- Stats now collected only at retire time (cold path)
- Header write kept at alloc time (freelist overlaps block[0])

A/B Result: -4.3% overhead → ±0% (target: legacy ±2%)
v7 OFF avg: 9.26M ops/s, v7 ON avg: 9.27M ops/s (+0.15%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-12 04:51:17 +09:00
parent 580e8f57f7
commit 17ceed619c
3 changed files with 204 additions and 44 deletions

View File

@ -456,7 +456,148 @@ v7-5 以降でも header を削除できるかの検証:
### 次世代開始チェックリスト
- [ ] HAKMEM_V2_GENERATION_SUMMARY.md が地図として機能
- [ ] v7-4 時点の設計メモ (本セクション) が読み返せる
- [ ] HakORune / JoinIR が一段落or 並行可能に)
- [ ] v7 research box は冷凍庫に保存完了
- [ ] HAKMEM_V2_GENERATION_SUMMARY.md と本ドキュメントから、v2→v7 の層構造と責務が一貫して読み取れること
- [ ] v7-4 時点の設計メモ本セクション)が「どこを伸ばすか/どこは ULTRA/MID に任せるか」の地図として機能していること
- [ ] v7 small/mid コアを C6 以外にも広げる際のクラス割り当てC2〜C7が `HAKMEM_V2_GENERATION_SUMMARY.md` と齟齬なく定義されていること
---
## 9. HAKMEM v3mimalloc に追いつく世代)のターゲット像
この節は、「いま以降の HAKMEM 開発は何を目指すか」をブレないようにするためのメモです。
### 9-1. 性能ターゲットMixed 161024B
- 評価プロファイル:
- `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE`
- `ws=400`, `iters=1,000,000`, size range `161024B`
- 比較対象:
- mimalloc: 現状 ~ 110120M ops/s
- HAKMEM v2 世代: ~ 4045M ops/sULTRA + MID v3 ベース)
- v3/v7 世代の目標:
- **短期**: 50M ops/s 台mimalloc の ~0.5×
- **中期**: 60M ops/s 近辺0.5〜0.6×)を安定して狙える設計
### 9-2. クラス別の役割v3 世代の前提)
`docs/analysis/HAKMEM_V2_GENERATION_SUMMARY.md` の整理を踏まえ、v3 世代では次の前提で進める:
- C7 (7691024B):
- L0 C7 ULTRA が本命。v7 small/mid コアからは除外し、ULTRA Box を前提に最適化を続ける。
- C6 (513768B):
- v7 SmallHeapCtx の本命クラス。
- C6-only v7 を最初のターゲットとして、legacy/MID/v6 を相手に A/B しながらコアの形を固める。
- C5 (257512B):
- 現状は MID v3 + ULTRA でそこそこ速く、本線としては安定。
- v7 への移行は C6 v7 が legacy/MID を上回るめどが立ってから、段階的に検討する。
- C4 (129256B):
- C4 ULTRA寄生型が効いている帯。v7 に乗せるかは慎重に検討。
- 当面は ULTRA を前提とし、v7 small コアには無理に載せない。
- C3C0 (≤64B):
- Tiny legacy/Tiny front v3 のまま。当座は v7 で触らない。
この前提により、「どのクラスを v7 small/mid コアで本気で攻めるか」「どこは ULTRA/MID/legacy に任せるか」が明確になる。
### 9-3. v7 コアで必ず守るルール
1. **Front は route するだけ**
- `size → class_idx → SmallPolicyV7.route_kind[class_idx] → switch` 以外の仕事ENV 読み・Region lookup・Segment 操作)は Front に置かない。
2. **HotBox は物理層に直接触らない**
- SmallObjectHotBox_v7 は `SmallSegment_v7` / `RegionIdBox` / `PageStatsBox` へのアクセスを ColdIface/API 経由に限定し、HotPath 内で ENV や Learner を直接参照しない。
3. **Learning は snapshot 経由のみ**
- L3 Policy/Learner は Stats を読んで `SmallPolicyV7` や per-class パラメータtls_cap, partial_limit 等)を更新する。
- L1/L0 は「いまの snapshot 値」を読むだけで、学習や ENV を意識しない。
### 9-4. v3 世代での「やってよい/やらない」境界
- やってよい(本筋):
- v7 small/mid コア(特に C6の alloc/free/segment/RegionId 経路の設計・実装・A/B。
- PolicyBox を使った route_kind の再配線ULTRA/MID/v7/LEGACY のクラスごとの切り替え)。
- RegionIdBox/Segment/PageStats の「共通物理層」としての整理と、small/mid/pool での再利用設計。
- やらない(この世代では控える):
- ULTRA 世代の大改造C7 ULTRA の構造変更など)。
- MID v3 のリフトアップを目的とした過度な再実装v7/mid コア側で吸収する)。
- header を全クラス・全経路から完全に消し去るような大手術(これは v8 以降のテーマとして温存)。
この節を「v3 / v7 世代で何を目指すか」の固定観念として扱い、今後の設計・実装・A/B で迷子になったときの基準とする。
---
## 10. Phase v7-5a: C6 v7 極限最適化 (Hot Path Stats Removal)
### 10-1. 目的
Phase v7-3 時点の -4.3% overhead を ±0% 以下に改善し、v7 を本線として使える状態にする。
### 10-2. v7-5a vs v7-5b の選択
| Option | 内容 | リスク | 期待効果 |
|--------|------|--------|----------|
| v7-5a | C6 micro-optimization (stats/header) | 低 | -4.3% → ±0% |
| v7-5b | Multi-class expansion (C5/C4) | 中 | overhead 分摊 |
**採用**: v7-5a を優先。低リスクで効果を確認してから v7-5b に進む。
### 10-3. v7-5a の最適化内容
#### 実施した最適化
1. **Per-page stats 削除 (hot path から)**:
- `alloc_count++` / `free_count++` / `live_current++/--` を hot path から除去
- Stats は retire 時に cold path で収集
2. **Global atomic stats の ENV-gating**:
- `HAKMEM_V7_HOT_STATS=1` で有効化デフォルトOFF
- Hot path での atomic counter を完全除去可能に
3. **Header-at-carve-time 最適化 → 断念**:
- 試行: 「refill 時にヘッダを書き、alloc 時には書かない」
- **失敗理由**: intrusive LIFO freelist が block[0..7] に next pointer を格納するため、
carve 時にヘッダを書いても alloc pop 前に上書きされる
- **対応**: ヘッダは alloc 時に書く方式を維持
```c
// freelist 構造の制約
// block[0]: header byte (1B)
// block[0..7]: freelist next pointer (8B)
// → 重複するため、carve 時にヘッダを書いても freelist が上書きする
```
### 10-4. A/B ベンチマーク結果
**ベンチ条件**:
- Range: 257-768B (C6-heavy)
- Benchmark: bench_mid_large_mt_hakmem
- 5 iterations each
| v7 OFF (MID v3) | v7 ON (v7-5a) |
|-----------------|---------------|
| 9,370,124 | 9,251,082 |
| 9,698,882 | 8,782,087 |
| 8,862,704 | 9,331,487 |
| 9,108,786 | 9,502,876 |
| 9,250,129 | 9,490,638 |
| **Avg: 9.26M** | **Avg: 9.27M** |
**結果: +0.15% (±0%, noise margin 内)**
### 10-5. 評価
| 指標 | Before (v7-3) | After (v7-5a) | 目標 |
|------|---------------|---------------|------|
| Overhead | -4.3% | ±0% | legacy ±2% |
| Stats impact | 常時 ON | ENV-gated | - |
| Header overhead | あり | あり (維持) | - |
**Phase v7-5a 達成**: hot path から per-page stats を除去し、overhead を ±0% まで改善。
### 10-6. 次のステップ候補
1. **v7-5b (Multi-class)**: C5/C4 へ v7 を拡張し、overhead をさらに分摊
2. **Headerless mode**: header 完全削除を再検討freelist 設計の変更が必要)
3. **Learner 連携**: Stats から動的 route 選択
---
**Document Updated**: 2025-12-12
**Phase v7-5a Status**: COMPLETE