Files
hakmem/docs/analysis/RANDOM_MIXED_BOTTLENECK_ANALYSIS.md
Moe Charm (CI) a9ddb52ad4 ENV cleanup: Remove BG/HotMag vars & guard fprintf (Larson 52.3M ops/s)
Phase 1 完了:環境変数整理 + fprintf デバッグガード

ENV変数削除(BG/HotMag系):
- core/hakmem_tiny_init.inc: HotMag ENV 削除 (~131 lines)
- core/hakmem_tiny_bg_spill.c: BG spill ENV 削除
- core/tiny_refill.h: BG remote 固定値化
- core/hakmem_tiny_slow.inc: BG refs 削除

fprintf Debug Guards (#if !HAKMEM_BUILD_RELEASE):
- core/hakmem_shared_pool.c: Lock stats (~18 fprintf)
- core/page_arena.c: Init/Shutdown/Stats (~27 fprintf)
- core/hakmem.c: SIGSEGV init message

ドキュメント整理:
- 328 markdown files 削除(旧レポート・重複docs)

性能確認:
- Larson: 52.35M ops/s (前回52.8M、安定動作)
- ENV整理による機能影響なし
- Debug出力は一部残存(次phase で対応)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 14:45:26 +09:00

413 lines
12 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.

# Random Mixed (128-1KB) ボトルネック分析レポート
**Analyzed**: 2025-11-16
**Performance Gap**: 19.4M ops/s → 23.4% of System (目標: 80%)
**Analysis Depth**: Architecture review + Code tracing + Performance pathfinding
---
## Executive Summary
Random Mixed が 23% で停滞している根本原因は、**複数の最適化層が C2-C764B-1KBの異なるクラスに部分的にしか適用されていない** ことです。Fixed-size 256B (40.3M ops/s) との性能差から、**class切り替え頻度と、各クラスの最適化カバレッジ不足** が支配的ボトルネックです。
---
## 1. Cycles 分布分析
### 1.1 レイヤー別コスト推定
| Layer | Target Classes | Hit Rate | Cycles | Assessment |
|-------|---|---|---|---|
| **HeapV2** | C0-C3 (8-64B) | 88-99% ✅ | **Low (2-3)** | Working well |
| **Ring Cache** | C2-C3 only | 0% (OFF) ❌ | N/A | Not enabled |
| **TLS SLL** | C0-C7 (全) | 0.7-2.7% | **Medium (8-12)** | Fallback only |
| **SuperSlab refill** | All classes | ~2-5% miss | **High (50-200)** | Dominant cost |
| **UltraHot** | C1-C2 | 11.7% | Medium | Disabled (Phase 19) |
### 1.2 支配的ボトルネック: SuperSlab Refill
**理由**:
1. **Refill頻度**: Random Mixed では class切り替え多発 → TLS SLL が複数クラスで頻繁に空になる
2. **Class-specific carving**: SuperSlab内の各slabは「1クラス専用」→ C4/C5/C6/C7 では carving/batch overhead が相対的に大きい
3. **Metadata access**: SuperSlab → TinySlabMeta → carving → SLL push の連鎖で 50-200 cycles
**Code Path** (`core/tiny_alloc_fast.inc.h:386-450` + `core/hakmem_tiny_refill_p0.inc.h`):
```
tiny_alloc_fast_pop() miss
tiny_alloc_fast_refill() called
sll_refill_batch_from_ss() or sll_refill_small_from_ss()
hak_super_registry lookup (linear search)
SuperSlab -> TinySlabMeta[] iteration (32 slabs)
carve_batch_from_slab() (write multiple fields)
tls_sll_push() (chain push)
```
### 1.3 ボトルネック確定
**最優先**: **SuperSlab refill コスト** (50-200 cycles/refill)
---
## 2. FrontMetrics 状況確認
### 2.1 実装状況
**実装完了** (`core/box/front_metrics_box.{h,c}`)
**Current Status** (Phase 19-4):
- HeapV2: C0-C3 で 88-99% ヒット率 → 本命層として機能中
- UltraHot: デフォルト OFF (Phase 19-4 で +12.9% 改善のため削除)
- FC/SFC: 実質 OFF
- TLS SLL: Fallback のみ (0.7-2.7%)
### 2.2 Fixed vs Random Mixed の構造的違い
| 側面 | Fixed 256B | Random Mixed |
|------|---|---|
| **使用クラス** | C5 のみ (100%) | C3, C5, C6, C7 (混在) |
| **Class切り替え** | 0 (固定) | 頻繁 (各iteration) |
| **HeapV2適用** | C5 には非適用 ❌ | C0-C3 のみ適用 (部分) |
| **TLS SLL hit率** | High (C5は SLL頼り) | Low (複数class混在) |
| **Refill頻度** | 低い (C5 warm) | **高い (class ごとに空)** |
### 2.3 「死んでいる層」の候補
**C4-C7 (128B-1KB) に対する最適化が極度に不足**:
| Class | Size | Ring | HeapV2 | UltraHot | Coverage |
|-------|---|---|---|---|---|
| C0 | 8B | ❌ | ✅ | ❌ | 1/3 |
| C1 | 16B | ❌ | ✅ | ❌ (OFF) | 1/3 |
| C2 | 32B | ❌ (OFF) | ✅ | ❌ (OFF) | 1/3 |
| C3 | 64B | ❌ (OFF) | ✅ | ❌ (OFF) | 1/3 |
| **C4** | **128B** | ❌ | ❌ | ❌ | **0/3** ← 完全未最適化 |
| **C5** | **256B** | ❌ | ❌ | ❌ | **0/3** ← 完全未最適化 |
| **C6** | **512B** | ❌ | ❌ | ❌ | **0/3** ← 完全未最適化 |
| **C7** | **1024B** | ❌ | ❌ | ❌ | **0/3** ← 完全未最適化 |
**衝撃的発見**: Random Mixed で使用されるクラスの **50%** (C5, C6, C7) が全く最適化されていない!
---
## 3. Class別パフォーマンスプロファイル
### 3.1 Random Mixed で使用されるクラス
コード分析 (`bench_random_mixed.c:77`):
```c
size_t sz = 16u + (r & 0x3FFu); // 16B-1040B の範囲
```
マッピング:
```
16-31B → C2 (32B) [16B requested]
32-63B → C3 (64B) [32-63B requested]
64-127B → C4 (128B) [64-127B requested]
128-255B → C5 (256B) [128-255B requested]
256-511B → C6 (512B) [256-511B requested]
512-1024B → C7 (1024B) [512-1023B requested]
```
**実際の分布**: ほぼ均一分布(ビット選択の性質上)
### 3.2 各クラスの最適化カバレッジ
**C0-C3 (HeapV2): 実装済みだが Random Mixed では使用量少ない**
- HeapV2 magazine capacity: 16/class
- Hit rate: 88-99%(実装は良い)
- **制限**: C4+ に対応していない
**C4-C7 (完全未最適化)**:
- Ring cache: 実装済みだが **デフォルト OFF** (`HAKMEM_TINY_HOT_RING_ENABLE=0`)
- HeapV2: C0-C3 のみ
- UltraHot: デフォルト OFF
- **結果**: 素の TLS SLL + SuperSlab refill に頼る
### 3.3 性能への影響
Random Mixed の大半は C4-C7 で処理されているのに、**全く最適化されていない**:
```
固定 256B での性能向上の理由:
- C5 単独 → HeapV2 未適用だが TLS SLL warm保持可能
- Class切り替えない → refill不要
- 結果: 40.3M ops/s
Random Mixed での性能低下の理由:
- C3/C5/C6/C7 混在
- 各クラス TLS SLL small → refill頻繁
- Refill cost: 50-200 cycles/回
- 結果: 19.4M ops/s (47% の性能低下)
```
---
## 4. 次の一手候補の優先度付け
### 候補分析
#### 候補A: Ring Cache を C4/C5 に拡張 🔴 最優先
**理由**:
- Phase 21-1 で既に **実装済み**`core/front/tiny_ring_cache.{h,c}`
- C2/C3 では未使用(デフォルト OFF
- C4-C7 への拡張は小さな変更で済む
- **効果**: ポインタチェイス削減 (+15-20%)
**実装状況**:
```c
// tiny_ring_cache.h:67-80
static inline int ring_cache_enabled(void) {
const char* e = getenv("HAKMEM_TINY_HOT_RING_ENABLE");
// デフォルト: 0 (OFF)
}
```
**有効化方法**:
```bash
export HAKMEM_TINY_HOT_RING_ENABLE=1
export HAKMEM_TINY_HOT_RING_C4=128
export HAKMEM_TINY_HOT_RING_C5=128
export HAKMEM_TINY_HOT_RING_C6=64
export HAKMEM_TINY_HOT_RING_C7=64
```
**推定効果**:
- 19.4M → 22-25M ops/s (+13-29%)
- TLS SLL pointer chasing: 3 mem → 2 mem
- Cache locality 向上
**実装コスト**: **LOW** (既存実装の有効化のみ)
---
#### 候補B: HeapV2 を C4/C5 に拡張 🟡 中優先度
**理由**:
- Phase 13-A で既に **実装済み**`core/front/tiny_heap_v2.h`
- 現在 C0-C3 のみ(`HAKMEM_TINY_HEAP_V2_CLASS_MASK=0xE`
- Magazine supply で TLS SLL hit rate 向上可能
**制限**:
- Magazine size: 16/class → Random Mixed では小さい
- Phase 17-1 実験: `+0.3%` のみ改善
- **理由**: Delegation overhead = TLS savings
**推定効果**: +2-5% (TLS refill削減)
**実装コスト**: LOWENV設定変更のみ
**判断**: Ring Cache の方が効果的候補A推奨
---
#### 候補C: C7 (1KB) 専用 HotPath 実装 🟢 長期
**理由**:
- C7 は Random Mixed の ~16% を占める
- SuperSlab refill cost が大きい
- 専用設計で carve/batch overhead 削減可能
**推定効果**: +5-10% (C7 単体で)
**実装コスト**: **HIGH** (新規設計)
**判断**: 後回しRing Cache + その他の最適化後に検討)
---
#### 候補D: SuperSlab refill の高速化 🔥 超長期
**理由**:
- 根本原因50-200 cycles/refillの直接攻撃
- Phase 12 (Shared SuperSlab Pool) でアーキテクチャ変更
- 877 SuperSlab → 100-200 に削減
**推定効果**: **+300-400%** (9.38M → 70-90M ops/s)
**実装コスト**: **VERY HIGH** (アーキテクチャ変更)
**判断**: Phase 21前提となる細かい最適化完了後に着手
---
### 優先順位付け結論
```
🔴 最優先: Ring Cache C4/C7 拡張 (実装済み、有効化のみ)
期待: +13-29% (19.4M → 22-25M ops/s)
工数: LOW
リスク: LOW
🟡 次点: HeapV2 C4/C5 拡張 (実装済み、有効化のみ)
期待: +2-5%
工数: LOW
リスク: LOW
判断: 効果が小さいRing優先
🟢 長期: C7 専用 HotPath
期待: +5-10%
工数: HIGH
判断: 後回し
🔥 超長期: SuperSlab Shared Pool (Phase 12)
期待: +300-400%
工数: VERY HIGH
判断: 根本解決Phase 21終了後
```
---
## 5. 推奨施策
### 5.1 即実施: Ring Cache 有効化テスト
**スクリプト** (`scripts/test_ring_cache.sh` の例):
```bash
#!/bin/bash
echo "=== Ring Cache OFF (Baseline) ==="
./out/release/bench_random_mixed_hakmem 500000 256 42
echo "=== Ring Cache ON (C4/C7) ==="
export HAKMEM_TINY_HOT_RING_ENABLE=1
export HAKMEM_TINY_HOT_RING_C4=128
export HAKMEM_TINY_HOT_RING_C5=128
export HAKMEM_TINY_HOT_RING_C6=64
export HAKMEM_TINY_HOT_RING_C7=64
./out/release/bench_random_mixed_hakmem 500000 256 42
echo "=== Ring Cache ON (C2/C3 original) ==="
export HAKMEM_TINY_HOT_RING_ENABLE=1
export HAKMEM_TINY_HOT_RING_C2=128
export HAKMEM_TINY_HOT_RING_C3=128
unset HAKMEM_TINY_HOT_RING_C4 HAKMEM_TINY_HOT_RING_C5 HAKMEM_TINY_HOT_RING_C6 HAKMEM_TINY_HOT_RING_C7
./out/release/bench_random_mixed_hakmem 500000 256 42
```
**期待結果**:
- Baseline: 19.4M ops/s (23.4%)
- Ring C4/C7: 22-25M ops/s (24-28%) ← +13-29%
- Ring C2/C3: 20-21M ops/s (23-24%) ← +3-8%
---
### 5.2 検証用 FrontMetrics 計測
**有効化**:
```bash
export HAKMEM_TINY_FRONT_METRICS=1
export HAKMEM_TINY_FRONT_DUMP=1
./out/release/bench_random_mixed_hakmem 500000 256 42 2>&1 | grep -A 100 "Frontend Metrics"
```
**期待出力**: クラス別ヒット率一覧Ring 有効化前後で比較)
---
### 5.3 長期ロードマップ
```
フェーズ 21-1: Ring Cache 有効化 (即実施)
├─ C2/C3 テスト(既実装)
├─ C4-C7 拡張テスト
└─ 期待: 20-25M ops/s (+13-29%)
フェーズ 21-2: Hot Slab Direct Index (Class5+)
└─ SuperSlab slab ループ削減
└─ 期待: 22-30M ops/s (+13-55%)
フェーズ 21-3: Minimal Meta Access
└─ 触るフィールド削減accessed pattern 限定)
└─ 期待: 24-35M ops/s (+24-80%)
フェーズ 22: Phase 12 (Shared SuperSlab Pool) 着手
└─ 877 SuperSlab → 100-200 削減
└─ 期待: 70-90M ops/s (+260-364%)
```
---
## 6. 技術的根拠
### 6.1 Fixed 256B (C5) vs Random Mixed (C3/C5/C6/C7)
**固定の高速性の理由**:
1. **Class 固定** → TLS SLL warm保持
2. **HeapV2 非適用** → でも SLL hit率高い
3. **Refill少ない** → class切り替えない
**Random Mixed の低速性の理由**:
1. **Class 頻繁切り替え** → TLS SLL → 複数class で枯渇
2. **各クラス refill多発** → 50-200 cycles × 多発
3. **最適化カバレッジ 0%** → C4-C7 が素のパス
**差分**: 40.3M - 19.4M = **20.9M ops/s**
素の TLS SLL と Ring Cache の差:
```
TLS SLL (pointer chasing): 3 mem accesses
- Load head: 1 mem
- Load next: 1 mem (cache miss)
- Update head: 1 mem
Ring Cache (array): 2 mem accesses
- Load from array: 1 mem
- Update index: 1 mem (同一cache line)
改善: 3→2 = -33% cycles
```
### 6.2 Refill Cost 見積もり
```
Random Mixed refill frequency:
- Total iterations: 500K
- Classes: 6 (C2-C7)
- Per-class avg lifetime: 500K/6 ≈ 83K
- TLS SLL typical warmth: 16-32 blocks
- Refill per 50 ops: ~1 refill per 50-100 ops
→ 500K × 1/75 ≈ 6.7K refills
Refill cost:
- SuperSlab lookup: 10-20 cycles
- Slab iteration: 30-50 cycles (32 slabs)
- Carving: 10-15 cycles
- Push chain: 5-10 cycles
Total: ~60-95 cycles/refill (average)
Impact:
- 6.7K × 80 cycles = 536K cycles
- vs 500K × 50 cycles = 25M cycles total
= 2.1% のみ
理由: refill は相対的に少ない、むしろ TLS hit rate の悪さと
class切り替え overhead が支配的
```
---
## 7. 最終推奨
| 項目 | 内容 |
|------|------|
| **最優先施策** | **Ring Cache C4/C7 有効化テスト** |
| **期待改善** | +13-29% (19.4M → 22-25M ops/s) |
| **実装期間** | < 1日 (ENV設定のみ) |
| **リスク** | 極低既実装有効化のみ |
| **成功条件** | 23-25M ops/s 到達 (25-28% of system) |
| **次ステップ** | Phase 21-2 (Hot Slab Cache) |
| **長期目標** | Phase 12 (Shared SS Pool) 70-90M ops/s |
---
**End of Analysis**