Files
hakmem/docs/analysis/FREE_DISPATCHER_ANALYSIS.md
Moe Charm (CI) 118c0e4857 Phase FREE-DISPATCHER-OPT-1: free dispatcher 統計計測
**目的**: free dispatcher(29%)の内訳を細分化して計測。

**実装内容**:
- FreeDispatchStats 構造体追加(ENV: HAKMEM_FREE_DISPATCH_STATS, default 0)
- カウンタ: total_calls / domain (tiny/mid/large) / route (ultra/legacy/pool/v6) / env_checks / route_for_class_calls
- hak_free_at / tiny_route_for_class / tiny_route_snapshot_init にカウンタ埋め込み
- 挙動変更なし(計測のみ、ENV OFF 時は overhead ゼロ)

**計測結果**:

Mixed 16-1024B (1M iter, ws=400):
- total=8,081, route_calls=267,967, env_checks=9
- BENCH_FAST_FRONT により大半は早期リターン
- route_for_class は主に alloc 側で呼ばれる(267k calls vs 8k frees)
- ENV check は初期化時の 9回のみ(snapshot 効果)

C6-heavy (257-768B, 1M iter, ws=400):
- total=500,099, route_calls=1,034, env_checks=9
- fg_classify_domain に到達する free が多い
- route_for_class 呼び出しは極小(snapshot 効果)

**結論**:
- ENV check は既に十分最適化されている(初期化時のみ)
- route_for_class は alloc 側での呼び出しが主で、free 側は snapshot で O(1)
- 次フェーズ(OPT-2)では別のアプローチを検討

**ドキュメント追加**:
- docs/analysis/FREE_DISPATCHER_ANALYSIS.md(新規)
- CURRENT_TASK.md に Phase FREE-DISPATCHER-OPT-1 セクション追加

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-11 21:21:40 +09:00

116 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# FREE_DISPATCHER_ANALYSIS
## 目的
free dispatcherhak_free_at → fg_classify_domain → fg_tiny_gate → ...)のルーティング層を分析し、最適化ポイントを特定する。
## 現状フロー
```
free(ptr)
hak_free_at(ptr, sz)
fg_classify_domain(ptr, sz)
├→ FG_DOMAIN_TINY → fg_tiny_gate → tiny_free_gate_try_fast
├→ FG_DOMAIN_MID → mid free path
└→ FG_DOMAIN_LARGE → large free path
```
### tiny domain 内のルート分岐
```
tiny_free_gate_try_fast(base, class_idx)
tiny_route_for_class(class_idx) を呼び出し
├→ ULTRA (C4-C7) → tiny_cX_ultra_free_fast()
├→ Tiny legacy → existing tiny free
├→ pool v1 → pool free
└→ core v6 (C6) → small_free_fast_v6()
```
### ENV 判定箇所(推定)
- tiny_route_for_class() 内部
- HAKMEM_SMALL_HEAP_V6_ENABLED
- HAKMEM_SMALL_HEAP_V3_ENABLED
- HAKMEM_POOL_V2_ENABLED / V1_ENABLED
- HAKMEM_TINY_CX_ULTRA_FREE_ENABLED (C4/C5/C6/C7)
- fg_classify_domain() 内部
- サイズ閾値判定tiny/mid/large 分岐)
## Phase FREE-DISPATCHER-OPT-1: 統計計測
実装内容:
- FreeDispatchStats 構造体ENV: HAKMEM_FREE_DISPATCH_STATS, default 0
- カウンタ:
- total_calls: free 全体呼び出し回数
- domain_tiny / domain_mid / domain_large: domain 分岐の内訳
- route_ultra / route_tiny_legacy / route_pool_v1 / route_core_v6: tiny domain 内の route 内訳
- env_checks: ENV 読み回数(概算)
- route_for_class_calls: tiny_route_for_class() 呼び出し回数
計測結果は次のセクションに記載。
## Phase FREE-DISPATCHER-OPT-1 計測結果
### Mixed 16-1024B (1M iter, ws=400)
```
[FREE_DISPATCH_STATS] total=8081 tiny=0 mid=8081 large=0 ultra=0 tiny_legacy=7 pool=0 v6=0 route_calls=267967 env_checks=9
Throughput = 44.7M ops/s
```
**分析**:
- total_calls: 8,081 (hak_free_at 呼び出し回数、BENCH_FAST_FRONT で早期リターンしている分を除く)
- domain_mid: 100% (8,081/8,081) - BENCH_FAST_FRONT により tiny domain は早期リターン済み
- route_for_class_calls: 267,967 (alloc 側でも呼ばれるため total より大きい)
- env_checks: 9 (tiny_route_snapshot_init() で 1回だけ ENV を読む設計が機能)
**重要な発見**:
1. BENCH_FAST_FRONT により大半の free は早期リターンしており、fg_classify_domain に到達するのは少数のみ
2. route_for_class は主に alloc 側で呼ばれている267k calls vs 8k frees
3. ENV check は初期化時の 9回のみで、ホットパスでは完全に排除されている
### C6-heavy (257-768B, 1M iter, ws=400)
```
[FREE_DISPATCH_STATS] total=500099 tiny=0 mid=500099 large=0 ultra=0 tiny_legacy=7 pool=0 v6=0 route_calls=1034 env_checks=9
```
**分析**:
- total_calls: 500,099 (1M operations の約半分が free)
- domain_mid: 100% (C6 は mid domain)
- route_for_class_calls: 1,034 (Mixed より大幅に少ない、C6-heavy では alloc が単純)
- env_checks: 9 (同様に初期化時のみ)
**コメント**:
- C6-heavy では BENCH_FAST_FRONT の効果が少なく、大半の free が fg_classify_domain に到達
- route_for_class の呼び出しが非常に少ない1k callsのは、C6 が既に snapshot 済みで LUT lookup のみで完結しているため
## Phase FREE-DISPATCHER-OPT-2 候補施策
### 候補 A: tiny domain 早期 return
**条件**: tiny domain が 90% 以上
**施策**: fg_classify_domain から tiny 判定を早期 return にし、mid/large 分岐を cold に追いやる
**期待**: domain 判定コスト削減、分岐予測向上
### 候補 B: route snapshot 化
**条件**: route_for_class_calls ≈ total_calls毎回呼ばれている
**施策**: route_kind[class_idx] を snapshot にして、free では table lookup のみ
**期待**: ENV check 削減、route 判定の O(1) 化
### 候補 C: mid/pool free gate 最適化
**条件**: mid domain がそこそこある10% 以上)
**施策**: mid/pool の free gate 分岐も route snapshot 化
**期待**: C6-heavy での改善
### 判断基準
- tiny > 90% → 候補 A + B
- route_calls ≈ total → 候補 B 優先
- mid > 10% → 候補 C も検討