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>
12 KiB
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-C7(64B-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
理由:
- Refill頻度: Random Mixed では class切り替え多発 → TLS SLL が複数クラスで頻繁に空になる
- Class-specific carving: SuperSlab内の各slabは「1クラス専用」→ C4/C5/C6/C7 では carving/batch overhead が相対的に大きい
- 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):
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%)
実装状況:
// tiny_ring_cache.h:67-80
static inline int ring_cache_enabled(void) {
const char* e = getenv("HAKMEM_TINY_HOT_RING_ENABLE");
// デフォルト: 0 (OFF)
}
有効化方法:
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削減)
実装コスト: LOW(ENV設定変更のみ)
判断: 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 の例):
#!/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 計測
有効化:
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)
固定の高速性の理由:
- Class 固定 → TLS SLL warm保持
- HeapV2 非適用 → でも SLL hit率高い
- Refill少ない → class切り替えない
Random Mixed の低速性の理由:
- Class 頻繁切り替え → TLS SLL → 複数class で枯渇
- 各クラス refill多発 → 50-200 cycles × 多発
- 最適化カバレッジ 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