# HAKMEM現状整理 - 何が実装済みで何が未実装か **日付:** 2025-10-26 **目的:** 混乱を解消、次のステップを明確化 --- ## 🏗️ HAKMEMの3層構造 ``` ┌─────────────────────────────────────────────────────────┐ │ HAKMEM Memory Allocator │ ├─────────────────────────────────────────────────────────┤ │ │ │ [Tiny Pool] 8B - 64B │ │ ├─ SuperSlab (2MB aligned, 32 slabs) │ │ ├─ TLS Magazine (fast cache) │ │ └─ Bitmap allocation │ │ │ │ [Mid Pool] 2KB - 64KB │ │ ├─ Buddy allocator │ │ ├─ ACE learning (CAP調整) │ │ └─ Bridge classes (40KB, 52KB) │ │ │ │ [Large Pool] 128KB - 1MB │ │ ├─ Buddy allocator │ │ ├─ ACE learning (CAP調整) │ │ └─ THP support │ │ │ └─────────────────────────────────────────────────────────┘ ``` --- ## 📊 各Poolの実装状況 ### Tiny Pool(8-64B) | 機能 | 状態 | 実装フェーズ | 説明 | |------|------|--------------|------| | **サイズクラス** | ✅ 固定 | Phase 6.0 | 8種固定(8,16,24,32,40,48,56,64B) | | **SuperSlab割当** | ✅ 動的 | Phase 6.22 | 初回アクセス時にmmap(2MB) | | **Bitmap管理** | ✅ 実装済み | Phase 6.0 | O(1)ブロック検索 | | **TLS Magazine** | ✅ 実装済み | Phase 4.0 | 固定CAP、高速キャッシュ | | **Magazine CAP** | ✅ 固定 | Phase 6.0 | クラスごと固定(2048/1024/...) | | **SuperSlab解放** | ❌ **未実装** | **Phase 7.6** | **← これを今から実装!** | **現状の問題:** ``` ✅ 割当は動的(必要な時だけ確保) ❌ 解放は固定(永遠保持) → メモリ168% overhead ``` **Phase 7.6目標:** ``` ✅ 割当は動的 ✅ 解放も動的(空なら返却) → メモリ30-50% overhead(-75%削減!) ``` --- ### Mid Pool(2KB-64KB) | 機能 | 状態 | 実装フェーズ | 説明 | |------|------|--------------|------| | **サイズクラス** | ✅ 固定 | Phase 6.21 | 7種固定(2,4,8,16,32KB + 40,52KB Bridge) | | **DYN1(動的1枠)** | ❌ **無効化** | Phase 6.21 | 「動的1個=固定と同じ」で削除 | | **Buddy allocator** | ✅ 実装済み | Phase 2.0 | ページベース割当 | | **ACE CAP学習** | ✅ 実装済み | Phase 6.21 | ヒット率ベースで動的調整 | | **Bridge classes** | ✅ 実装済み | Phase 6.21 | 32-64KBギャップ埋め(固定) | | **W_MAX丸め** | ✅ 実装済み | Phase 6.0 | UCB1学習 | **現状:** ``` ✅ サイズクラス:固定7個 ✅ CAP:動的(ACEで学習) ✅ 境界:動的(W_MAX学習) ❌ クラス数:固定(DYN1無効化済み) ``` **Phase 6.21の決定:** - DYN1を無効化 - 固定Bridgeクラスに置き換え - 理由:「動的1個だけ = 固定と同じ」 --- ### Large Pool(128KB-1MB) | 機能 | 状態 | 実装フェーズ | 説明 | |------|------|--------------|------| | **サイズクラス** | ✅ 固定 | Phase 2.0 | 5種固定(64,128,256,512KB,1MB) | | **Buddy allocator** | ✅ 実装済み | Phase 2.0 | ページベース割当 | | **ACE CAP学習** | ✅ 実装済み | Phase 6.21 | ヒット率ベースで動的調整 | | **THP support** | ✅ 実装済み | Phase 6.0 | 2MB+ でTransparent Huge Pages | **現状:** ``` ✅ サイズクラス:固定5個 ✅ CAP:動的(ACEで学習) ✅ THP:有効 ``` --- ## 🎓 ACEの範囲(復習) ### ACEが最適化するもの **対象:** Mid Pool & Large Pool のみ **最適化項目:** | 項目 | Mid Pool | Large Pool | Tiny Pool | |------|----------|------------|-----------| | CAP(在庫量) | ✅ 動的 | ✅ 動的 | ❌ 固定 | | W_MAX(丸め) | ✅ 動的 | ❌ 固定 | ❌ 固定 | | しきい値 | ✅ 動的 | ✅ 動的 | ❌ N/A | | サイズクラス数 | ❌ 固定 | ❌ 固定 | ❌ 固定 | **学習手法:** - UCB1バンディット(W_MAX) - ヒット率ベース(CAP) - Canary方式(しきい値) **Tiny Poolは対象外:** - サイズ範囲が狭い(8-64B) - 固定最適化で十分(ヒット率90%+) - ACE追加の価値なし --- ## 🔍 DYN1無効化の経緯 ### Phase 6.21以前(DYN1あり) ```c // Mid Pool 2KB, 4KB, 8KB, 16KB, 32KB // 固定5クラス + DYN1 (動的1枠) // 学習で最適位置決定 // 例: DYN1 = 6KB に収束 実質: 2KB, 4KB, 6KB, 8KB, 16KB, 32KB ``` **問題点:** - 学習しても結局固定値に収束 - 「動的1個」 = 最終的に固定 - 複雑さだけ増える - 性能向上なし ### Phase 6.21(DYN1無効化) ```c // Mid Pool 2KB, 4KB, 8KB, 16KB, 32KB // 固定5クラス + 40KB, 52KB // Bridge classes(固定追加) ``` **理由:** - 最初から最適な固定値を入れる方が良い - DYN1の「動的」は見せかけ - Bridgeで32-64KBギャップ解消 **結論:** > **「動的1個だけ = 固定と同じ」** > (あなたの指摘が正しかった!) --- ## 🎯 Phase 7.6の位置づけ ### Phase 7.6 ≠ サイズクラスの動的化 **Phase 7.6は:** - ❌ Mid/Large のサイズクラス動的化 **ではない** - ✅ **Tiny Pool の SuperSlab解放** のみ ### なぜTiny Poolだけ? **理由1:問題が異なる** ``` Mid/Large: サイズクラスの最適化(DYN1) → Phase 6.21で固定Bridgeに変更済み Tiny Pool: メモリ解放の問題 → Phase 7.6で動的解放を実装 ``` **理由2:手法が異なる** ``` Mid/Large: 学習ベース(ACE) → CAP、W_MAX を学習 Tiny Pool: 設計ベース(Bitmap) → SuperSlabライフサイクルを動的に ``` **理由3:効果が異なる** ``` Mid/Large DYN1: 性能向上なし(無効化済み) Tiny SuperSlab: メモリ75%削減!(Phase 7.6) ``` --- ## 📋 現状まとめ ### 実装済み(変更なし) | Pool | 項目 | 状態 | |------|------|------| | Tiny | サイズクラス | ✅ 固定8種 | | Tiny | Magazine CAP | ✅ 固定 | | Tiny | SuperSlab割当 | ✅ 動的 | | Mid | サイズクラス | ✅ 固定7種(Bridge含む) | | Mid | DYN1 | ❌ 無効化済み | | Mid | ACE CAP学習 | ✅ 動的 | | Large | サイズクラス | ✅ 固定5種 | | Large | ACE CAP学習 | ✅ 動的 | ### Phase 7.6で実装(未実装) | Pool | 項目 | 状態 | |------|------|------| | **Tiny** | **SuperSlab解放** | ❌ **未実装** ← これをやる! | --- ## 🚀 今からやること ### Phase 7.6: Tiny SuperSlab 動的解放 **目標:** 空SuperSlabをOSに返却 **実装:** 1. ✅ 追跡インフラ(完了) - `total_active_blocks` カウンタ追加済み 2. ⏸️ Magazine統合(これから) - Magazine free時にカウンタ減算 - 空検出可能に 3. ⏸️ 解放ロジック(これから) - `total_active_blocks == 0` で `superslab_free()` - OSに2MB返却 **効果:** ``` 現状: 40.8 MB RSS (168% overhead) ↓ Phase 7.6: 17-20 MB RSS (30-50% overhead) ↓ -75% メモリ削減! ``` **実装量:** ~75行、2-3時間 --- ## 🎓 やらないこと ### 1. Mid/Large サイズクラスの動的化 **理由:** - Phase 6.21でDYN1無効化済み - 「動的1個 = 固定と同じ」 - 価値なし **もしやるなら:** - 全クラス動的化必要(DYN1-DYN7) - 複雑さ増大 - 性能劣化リスク - **推奨しない** ### 2. Tiny Magazine CAPの動的化 **理由:** - 現状で十分高性能(ヒット率90%+) - 固定CAPで最適 - ACE追加の価値なし ### 3. SuperSlabサイズの動的化 **理由:** - 2MBが最適(mimalloc準拠) - 変更の価値なし --- ## 🎯 次のステップ ### 推奨:Phase 7.6(Tiny SuperSlab解放) **理由:** - ✅ 効果MAX(メモリ75%削減) - ✅ 実装量小(~75行) - ✅ 論文価値高 - ✅ すでに計画済み **実装順序:** ``` Step 1: Magazine統合 (~15行) ↓ Step 2: Magazine spill対応 (~10行) ↓ Step 3: 空SuperSlab解放 (~30行) ↓ Step 4: 遅延割当明示 (~20行) ``` ### 代替案:Mid/Large動的化(非推奨) **もしやるなら:** - DYN1-DYN7を全実装 - 実装量 ~300行 - 時間 1-2週間 - 効果 不明(Phase 6.21で無効化した理由あり) **推奨しない理由:** - Phase 6.21の決定を覆す - 「動的1個問題」再発 - 複雑さ増大 --- ## 📊 図解:何をやるのか ### Phase 7.6(推奨) ``` 対象: Tiny Pool (8-64B) Before: SuperSlab割当: 動的 ✅ SuperSlab解放: 固定 ❌ ← 問題 ↓ メモリ168% overhead After: SuperSlab割当: 動的 ✅ SuperSlab解放: 動的 ✅ ← 解決! ↓ メモリ30-50% overhead ``` ### Mid/Large動的化(非推奨) ``` 対象: Mid/Large Pool (2KB-1MB) Before (Phase 6.21): サイズクラス: 固定 ✅ CAP: 動的(ACE) ✅ DYN1: 無効化 ✅ ↓ 性能・メモリ最適 After(もし実装したら): サイズクラス: 動的? CAP: 動的(ACE) ✅ DYN1-7: 全動的? ↓ 複雑化、効果不明 ``` --- ## 🎯 結論 ### やること **Phase 7.6: Tiny SuperSlab動的解放** - ✅ 効果明確(メモリ75%削減) - ✅ 実装量小(~75行) - ✅ 論文価値高 - ✅ すでに追跡インフラ完成 ### やらないこと **Mid/Large サイズクラス動的化** - ❌ Phase 6.21で無効化済み - ❌ 「動的1個問題」 - ❌ 複雑化リスク - ❌ 効果不明 --- ## 🐱 にゃーん!わかりましたか? **次の質問:** 1. **Phase 7.6を実装する?** → Step 1(Magazine統合)から開始 2. **Mid/Large動的化をやりたい?** → Phase 6.21の決定を再検討 → DYN1復活の是非を議論 3. **もっと説明が必要?** → どこが混乱しているか教えてください **どれにしますか?** 🎯