Added: - Section 4: Phase 16 A/B Testing results (Dynamic Tiny/Mid boundary) - Section 5: Phase 17 Small-Mid Box design plan (256B-4KB dedicated layer) - Updated TODO list for Phase 17 implementation Phase 16 Conclusion: - Reducing Tiny coverage (C0-C5) caused -76% to -79% performance degradation - Mid's coarse size classes (8KB/16KB/32KB) are inefficient for small sizes - Recommendation: Keep default HAKMEM_TINY_MAX_CLASS=7 Phase 17 Plan: - New Small-Mid allocator box for 256B-4KB range - Dedicated SuperSlab pool (separated from Tiny to avoid Phase 12 churn) - 5 size classes: 256B/512B/1KB/2KB/4KB - Target: 10M-20M ops/s (2-4x improvement over current Tiny C6/C7) - ENV control: HAKMEM_SMALLMID_ENABLE=1 for A/B testing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
14 KiB
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の二段構えに整理。
- free ラッパが外部ポインタまで
-
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 の「誰も扱わない帯」は解消済み。
- PoolTLS Phase 完了(Mid-Large MT ベンチ)
-
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% を消費。
- HAKMEM 所有かチェックせず、すべての
3.2 修正内容(Phase 15)
- free ラッパ側:
- 軽量なドメインチェックを追加:
- Tiny/Pool 用の header magic を安全に読んで、HAKMEM 所有の可能性があるものだけ
hak_free_atへ。 - そうでない(BenchMeta/外部)ポインタは
__libc_freeへ。
- Tiny/Pool 用の header magic を安全に読んで、HAKMEM 所有の可能性があるものだけ
- 軽量なドメインチェックを追加:
- 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 オーバーヘッドは軽微、むしろ微増。
- 256B 固定:
- 安定性:
- 全サイズ(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先生分析):
- Mid 箱の前提が「8KB〜用」になっている
- 256B/512B/1024B では 8KB ページをほぼ1〜数個のブロックのために確保 → 非効率
- パス長も Mid の方が長い(PoolTLS / mid registry / page 管理)
- 「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先生レビュー済み ✅)
-
専用SuperSlab分離
- Small-Mid 専用の SuperSlab プールを用意
- Tiny の SuperSlab とは完全分離(競合なし)
- Phase 12 のチャーン問題を回避(最重要!)
-
サイズクラス
- Small-Mid: 256B / 512B / 1KB / 2KB / 4KB (5 classes)
- Tiny 側は変更なし(C0-C5 維持)
- クラス数増加を最小限に抑える
-
技術流用
- Header-based fast free (Phase 7 の実績技術)
- TLS SLL freelist (Tiny と同じ構造)
- Box理論による明確な境界(一方向依存)
-
境界設計
Tiny: 0-255B (C0-C5, 現在の設計そのまま) Small-Mid: 256B-4KB (新設, 細かいサイズクラス) Mid: 8KB-32KB (既存, ページ単位で効率的) -
ENV制御
HAKMEM_SMALLMID_ENABLE=1で ON/OFF- A/B テスト可能(デフォルト OFF)
5.3 実装ステップ
-
Small-Mid 専用ヘッダー作成 (
core/hakmem_smallmid.h)- 5 size classes 定義
- TLS freelist 構造
- Fast alloc/free API
-
専用 SuperSlab バックエンド (
core/hakmem_smallmid_superslab.c)- Small-Mid 専用 SuperSlab プール
- Tiny SuperSlab とは完全分離
- スパン予約・解放ロジック
-
Fast alloc/free path (
core/smallmid_alloc_fast.inc.h)- Header-based fast free (Phase 7 流用)
- TLS SLL pop/push (Tiny と同じ)
- Bump allocation fallback
-
ルーティング統合 (
hak_alloc_api.inc.h)if (size <= 255) → Tiny else if (size <= 4096) → Small-Mid // NEW! else if (size <= 32768) → Mid else → ACE / mmap -
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 実装 🚧
-
ヘッダー作成 (
core/hakmem_smallmid.h)- 5 size classes 定義 (256B/512B/1KB/2KB/4KB)
- TLS freelist 構造体定義
- size → class マッピング関数
- Fast alloc/free API 宣言
-
専用 SuperSlab バックエンド (
core/hakmem_smallmid_superslab.c)- Small-Mid 専用 SuperSlab プール(Tiny と完全分離)
- スパン予約・解放ロジック
- refill 関数
-
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
-
ルーティング統合 (
hak_alloc_api.inc.h)- Small-Mid 層の追加(256B-4KB)
- ENV で ON/OFF 切り替え
-
A/B ベンチマーク
- Config A: Small-Mid OFF(現状)
- Config B: Small-Mid ON(新実装)
- 256B/512B/1KB/2KB/4KB で性能測定
-
ドキュメント作成
PHASE17_SMALLMID_BOX_DESIGN.md- 設計書PHASE17_SMALLMID_AB_RESULTS.md- A/B テスト結果
7.2 その他タスク(Phase 17 後)
-
Phase 16 結果の詳細分析
- ✅ 完了 - CURRENT_TASK.md に記録済み
-
C2/C3 UltraHot のコード掃除
- C4/C5 関連の定義・分岐を ENV ガードか別 Box に切り出し
- デフォルト構成では C2/C3 だけを対象とする形に簡素化
-
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ヘッダー作成開始