# CURRENT TASK (Phase 14–17 Snapshot) – Tiny / Mid / ExternalGuard / Small-Mid **Last Updated**: 2025-11-16 **Owner**: ChatGPT → Phase 17 実装中: Claude Code **Size**: 約 300 行(Claude 用コンテキスト簡略版) --- ## 1. 全体の現在地(どこまで終わっているか) - Tiny (0–1023B) - NEW 3-layer front(bump / small_mag / slow)安定。 - TinyHeapV2: 「alloc フロント+統計」は実装済みだが、実運用は **C2/C3 を UltraHot に委譲**。 - TinyUltraHot(Phase 14): - C2/C3(16B/32B)専用 L0 ultra-fast path(Stealing モデル)。 - 固定サイズベンチで +16〜36% 改善、hit 率 ≈ 100%。 - Box 分離(Phase 15): - free ラッパが外部ポインタまで `hak_free_at` に投げていた問題を修正。 - BenchMeta(slots など)→ 直接 `__libc_free`、CoreAlloc(Tiny/Mid)→ `hak_free_at` の二段構えに整理。 - Mid / PoolTLS(1KB–32KB) - PoolTLS Phase 完了(Mid-Large MT ベンチ) - ~10.6M ops/s(system malloc より速い構成あり)。 - lock contention(futex 68%)を lock-free MPSC + bind box で大幅削減。 - GAP 修正(Tiny 1023B / Mid 1KB〜): - `TINY_MAX_SIZE=1023` / `MID_MIN_SIZE=1024` で 1KB–8KB の「誰も扱わない帯」は解消済み。 - Shared SuperSlab Pool(Phase 12 – SP-SLOT Box) - 1 SuperSlab : 多 class 共有 + SLOT_UNUSED/ACTIVE/EMPTY 追跡。 - SuperSlab 数: 877 → 72(-92%)、mmap/munmap: -48%、Throughput: +131%。 - Lock contention P0-5 まで実装済み(Stage 2 lock-free claiming)。 - ExternalGuard(Phase 15) - UNKNOWN ポインタ(Tiny/Pool/Mid/L25/registry どこでも捕まらないもの)を最後の箱で扱う。 - 挙動: - `hak_super_lookup` など全て miss → mincore でページ確認 → 原則「解放せず leak 扱い(安全優先)」。 - Phase 15 修正で: - BenchMeta のポインタを CoreAlloc に渡さなくなり、UNKNOWN 呼び出し回数が激減。 - `mincore` の CPU 負荷もベンチではほぼ無視できるレベルまで縮小。 --- ## 2. Tiny 性能の現状(Phase 14–15 時点) ### 2.1 Fixed-size Tiny ベンチ(HAKMEM vs System) `bench_fixed_size_hakmem` / `bench_fixed_size_system`(workset=128, 500K iterations 相当) | Size | HAKMEM (Phase 15) | System malloc | 比率 | |--------|-------------------|---------------|----------| | 128B | ~16.6M ops/s | ~90M ops/s | ~18.5% | | 256B | ~16.2M ops/s | ~89.6M ops/s | ~18.1% | | 512B | ~15.0M ops/s | ~90M ops/s | ~16.6% | | 1024B | ~15.1M ops/s | ~90M ops/s | ~16.8% | 状態: - クラッシュは完全解消(workset=64/128 で長尺 500K iter も安定)。 - Tiny UltraHot + 学習層 + ExternalGuard の組み合わせは「正しさ」は OK。 - 性能は system の ~16–18% レベル(約 5–6× 遅い)→ まだ大きな伸びしろあり。 ### 2.2 C2/C3 UltraHot 専用ベンチ 固定サイズ(100K iterations, workset=128) | Size | Baseline (UltraHot OFF) | UltraHot ON | 改善率 | Hit Rate | |------|-------------------------|-------------|-------------|---------| | 16B | ~40.4M ops/s | ~55.0M | +36.2% 🚀 | ≈100% | | 32B | ~43.5M ops/s | ~50.6M | +16.3% 🚀 | ≈100% | Random Mixed 256B: - Baseline: ~8.96M ops/s - UltraHot ON: ~8.81M ops/s(-1.6%、誤差〜軽微退化) - 理由: C2/C3 が全体の 1–2% のみ → UltraHot のメリットが平均に薄まる。 結論: - C2/C3 UltraHot は **ターゲットクラスに対しては実用級の Box**。 - 他ワークロードでは「ほぼ影響なし(わずかな分岐オーバーヘッドのみ)」の範囲に収まっている。 --- ## 3. Phase 15: ExternalGuard / Domain 分離の成果 ### 3.1 以前の問題 - free ラッパ(`core/box/hak_wrappers.inc.h`)が: - HAKMEM 所有かチェックせず、すべての `free(ptr)` を `hak_free_at(ptr, …)` に投げていた。 - その結果: - ベンチ内部 `slots`(`calloc(256, sizeof(void*))` の 2KB など)も CoreAlloc に流入。 - `classify_ptr` → UNKNOWN → ExternalGuard → mincore → 「解放せず leak」と判定。 - ベンチ観測: - 約 0.84% の leak(BenchMeta がどんどん漏れる)。 - `mincore` が Tiny ベンチ CPU の ~13% を消費。 ### 3.2 修正内容(Phase 15) - free ラッパ側: - 軽量なドメインチェックを追加: - Tiny/Pool 用の header magic を安全に読んで、HAKMEM 所有の可能性があるものだけ `hak_free_at` へ。 - そうでない(BenchMeta/外部)ポインタは `__libc_free` へ。 - ExternalGuard: - UNKNOWN ポインタを「解放しない(leak)」方針に明示的変更。 - デバッグ時のみ `HAKMEM_EXTERNAL_GUARD_LOG=1` で原因特定用ログを出す。 ### 3.3 結果 - Leak 率: - 100K iter: 840 leaks → 0.84% - 500K iter: ~4200 leaks → 0.84% - ほぼ全部が BenchMeta / 外部ポインタであり、CoreAlloc 側の漏れではないと確認。 - 性能: - 256B 固定: - Before: 15.9M ops/s - After: 16.2M ops/s(+1.9%)→ domain check オーバーヘッドは軽微、むしろ微増。 - 安定性: - 全サイズ(128/256/512/1024B)で 500K iter 完走(クラッシュなし)。 - ExternalGuard 経由の「危ない free」は leak に封じ込められた。 **要点:** Box 境界違反(BenchMeta→CoreAlloc 流入)はほぼ完全に解消。 ベンチでの mincore / ExternalGuard コストも許容範囲になった。 --- ## 4. Phase 16: Dynamic Tiny/Mid Boundary A/B Testing(2025-11-16完了) ### 4.1 実装内容 ENV変数でTiny/Mid境界を動的調整可能にする機能を追加: - `HAKMEM_TINY_MAX_CLASS=7` (デフォルト): Tiny が 0-1023B を担当 - `HAKMEM_TINY_MAX_CLASS=5` (実験用): Tiny が 0-255B のみ担当 実装ファイル: - `hakmem_tiny.h/c`: `tiny_get_max_size()` - ENV読取とクラス→サイズマッピング - `hakmem_mid_mt.h/c`: `mid_get_min_size()` - 動的境界調整(サイズギャップ防止) - `hak_alloc_api.inc.h`: 静的TINY_MAX_SIZEを動的呼び出しに変更 ### 4.2 A/B Benchmark Results | Size | Config A (C0-C7) | Config B (C0-C5) | 変化率 | |------|------------------|------------------|--------| | 128B | 6.34M ops/s | 1.38M ops/s | **-78%** ❌ | | 256B | 6.34M ops/s | 1.36M ops/s | **-79%** ❌ | | 512B | 5.55M ops/s | 1.33M ops/s | **-76%** ❌ | | 1024B | 5.91M ops/s | 1.37M ops/s | **-77%** ❌ | ### 4.3 発見と結論 ✅ **成功**: サイズギャップ修正完了(OOMクラッシュなし) ❌ **失敗**: Tiny カバレッジ削減で大幅な性能劣化 (-76% ~ -79%) ⚠️ **根本原因**: Mid の粗いサイズクラス (8KB/16KB/32KB) が小サイズで非効率 - Mid は 8KB ページ単位の設計 → 256B-1KB を投げると 8KB ページをほぼ数ブロックのために確保 - ページ fault・TLB・メタデータコストが相対的に巨大 - Tiny は slab + freelist で高密度 → 同じサイズでも桁違いに効率的 **教訓(ChatGPT先生分析)**: 1. Mid 箱の前提が「8KB〜用」になっている - 256B/512B/1024B では 8KB ページをほぼ1〜数個のブロックのために確保 → 非効率 2. パス長も Mid の方が長い(PoolTLS / mid registry / page 管理) 3. 「Tiny を削って Mid に任せれば軽くなる」という仮説は、現行の "8KB〜前提の Mid 設計" では成り立たない **推奨**: **デフォルト HAKMEM_TINY_MAX_CLASS=7 (C0-C7) を維持** --- ## 5. Phase 17: Small-Mid Allocator Box(256B-4KB専用層)【実装中】 ### 5.1 目標 **問題**: Tiny C6/C7 (512B/1KB) が 5.5M-5.9M ops/s → system malloc の ~6% レベル **目標**: Small-Mid 専用層で **10M-20M ops/s** に改善、Tiny/Mid の間のギャップを埋める ### 5.2 設計原則(ChatGPT先生レビュー済み ✅) 1. **専用SuperSlab分離** - Small-Mid 専用の SuperSlab プールを用意 - Tiny の SuperSlab とは完全分離(競合なし) - **Phase 12 のチャーン問題を回避**(最重要!) 2. **サイズクラス** - Small-Mid: 256B / 512B / 1KB / 2KB / 4KB (5 classes) - Tiny 側は変更なし(C0-C5 維持) - クラス数増加を最小限に抑える 3. **技術流用** - Header-based fast free (Phase 7 の実績技術) - TLS SLL freelist (Tiny と同じ構造) - Box理論による明確な境界(一方向依存) 4. **境界設計** ``` Tiny: 0-255B (C0-C5, 現在の設計そのまま) Small-Mid: 256B-4KB (新設, 細かいサイズクラス) Mid: 8KB-32KB (既存, ページ単位で効率的) ``` 5. **ENV制御** - `HAKMEM_SMALLMID_ENABLE=1` で ON/OFF - A/B テスト可能(デフォルト OFF) ### 5.3 実装ステップ 1. **Small-Mid 専用ヘッダー作成** (`core/hakmem_smallmid.h`) - 5 size classes 定義 - TLS freelist 構造 - Fast alloc/free API 2. **専用 SuperSlab バックエンド** (`core/hakmem_smallmid_superslab.c`) - Small-Mid 専用 SuperSlab プール - Tiny SuperSlab とは完全分離 - スパン予約・解放ロジック 3. **Fast alloc/free path** (`core/smallmid_alloc_fast.inc.h`) - Header-based fast free (Phase 7 流用) - TLS SLL pop/push (Tiny と同じ) - Bump allocation fallback 4. **ルーティング統合** (`hak_alloc_api.inc.h`) ```c if (size <= 255) → Tiny else if (size <= 4096) → Small-Mid // NEW! else if (size <= 32768) → Mid else → ACE / mmap ``` 5. **A/B ベンチマーク** - Config A: Small-Mid OFF (現状) - Config B: Small-Mid ON (新実装) - 256B / 512B / 1KB / 2KB / 4KB で比較 ### 5.4 懸念点と対策(ChatGPT先生指摘) ❌ **懸念1**: SuperSlab 共有の競合 - **対策**: Small-Mid が「自分専用のスパン」を予約して、その中だけで完結する境界設計 ❌ **懸念2**: クラス数の増加 - **対策**: Tiny 側のクラスは増やさない(C0-C5 そのまま)、Small-Mid は 5 クラスに抑える ❌ **懸念3**: メタデータオーバーヘッド - **対策**: TLS state + サイズクラス配列のみ(数KB程度)、影響は最小限 ### 5.5 期待される効果 - **性能改善**: 256B-1KB で 5.5M → 10-20M ops/s (目標 2-4倍) - **ギャップ解消**: Tiny (6M) と Mid (?) の間を埋める - **Box 理論的健全性**: 境界明確、一方向依存、A/B 可能 ### 5.6 実装状況 🚧 **IN PROGRESS** - 設計方針確定、実装開始準備中 --- ## 6. 未達成の目標・残課題(次フェーズ候補) ### 6.1 Tiny 性能ギャップ(System の ~18% 止まり) 現状: - System malloc が ~90M ops/s レベルのところ、 - HAKMEM は 128〜1024B 固定で ~15–16M ops/s(約 18%)。 原因の切り分け(これまでの調査から): - Front(UltraHot/TinyHeapV2/TLS SLL)のパス長はかなり短縮済み。 - L1 dcache miss / instructions / branches は Phase 14 で大幅削減済みだが、 - まだ Tiny が 0–1023B を全部抱えており、 - 特に 512/1024B が Superslab/Pool 側のメタ負荷に効いている可能性。 候補: - **Phase 17 で実装中!** Small-Mid Box(256B〜4KB 専用箱)を設計し、Tiny/Mid の間を分離する。 - 詳細は § 5. Phase 17 を参照 ### 6.2 UltraHot/TinyHeapV2 の拡張 or 整理 - C2/C3 UltraHot は成功(16/32B 用)。 - C4/C5 まで拡張した試み(Phase 14-B)は: - Fixed-size では改善あり。 - Random Mixed で shared_pool_acquire_slab() が 47.5% まで膨らみ、大退化。 - 原因: Superslab/TLS 在庫のバランスを壊す「窃取カスケード」。 方針: - UltraHot は **C2/C3 専用 Box** に戻す(C4/C5 は一旦対象外にする)。 - もし C4/C5 を最適化したいなら、SmallMid Box の中で別設計する。 ### 6.3 ExternalGuard の統計と自動アラート - 現在: - `HAKMEM_EXTERNAL_GUARD_STATS=1` で統計を手動出力。 - 100+ 回呼ばれたら WARNING を出すのみ。 - 構想: - 「ExternalGuard 呼び出しが一定閾値を超えたら、自動で簡易レポートを吐く」Box を追加。 - 例: Top N 呼び出し元アドレス、サイズ帯、mincore 結果 など。 --- ## 7. Claude Code 君向け TODO(Phase 17 実装リスト) ### 7.1 Phase 17: Small-Mid Box 実装 🚧 1. **ヘッダー作成** (`core/hakmem_smallmid.h`) - 5 size classes 定義 (256B/512B/1KB/2KB/4KB) - TLS freelist 構造体定義 - size → class マッピング関数 - Fast alloc/free API 宣言 2. **専用 SuperSlab バックエンド** (`core/hakmem_smallmid_superslab.c`) - Small-Mid 専用 SuperSlab プール(Tiny と完全分離) - スパン予約・解放ロジック - refill 関数 3. **Fast alloc/free 実装** (`core/smallmid_alloc_fast.inc.h`, `core/hakmem_smallmid.c`) - Header-based fast free (Phase 7 技術流用) - TLS SLL pop/push (Tiny と同じ構造) - Bump allocation fallback - ENV 制御: `HAKMEM_SMALLMID_ENABLE=1` 4. **ルーティング統合** (`hak_alloc_api.inc.h`) - Small-Mid 層の追加(256B-4KB) - ENV で ON/OFF 切り替え 5. **A/B ベンチマーク** - Config A: Small-Mid OFF(現状) - Config B: Small-Mid ON(新実装) - 256B/512B/1KB/2KB/4KB で性能測定 6. **ドキュメント作成** - `PHASE17_SMALLMID_BOX_DESIGN.md` - 設計書 - `PHASE17_SMALLMID_AB_RESULTS.md` - A/B テスト結果 ### 7.2 その他タスク(Phase 17 後) 1. **Phase 16 結果の詳細分析** - ✅ 完了 - CURRENT_TASK.md に記録済み 2. **C2/C3 UltraHot のコード掃除** - C4/C5 関連の定義・分岐を ENV ガードか別 Box に切り出し - デフォルト構成では C2/C3 だけを対象とする形に簡素化 3. **ExternalGuard 統計の自動化** - 閾値超過時の自動レポート機能 この CURRENT_TASK.md は、あくまで「Phase 14–17 周辺の簡略版メモ」です。 より過去の詳細な経緯は `CURRENT_TASK_FULL.md` や各 PHASE レポートを参照してください。 --- ## 8. Phase 17 実装ログ(進行中) ### 2025-11-16 - ✅ Phase 16 完了・A/B テスト結果分析 - ✅ ChatGPT 先生の Small-Mid Box 提案レビュー - ✅ CURRENT_TASK.md 更新(Phase 17 設計方針確定) - 🚧 次: `core/hakmem_smallmid.h` ヘッダー作成開始