116 lines
4.1 KiB
Markdown
116 lines
4.1 KiB
Markdown
|
|
# FREE_DISPATCHER_ANALYSIS
|
|||
|
|
|
|||
|
|
## 目的
|
|||
|
|
|
|||
|
|
free dispatcher(hak_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 も検討
|