# hakmem Architecture Design - 設計思想と技術詳細 **対象**: 技術者・実装者・研究者 --- ## 🧠 設計理念の進化 ### **第1世代: 複雑な学習アプローチ (Phase 1-6.5)** ```c // 過去の複雑設計 ✅ Call-siteプロファイリング ✅ ACE (Agentic Context Engineering) ✅ UCB1バンディット学習 ✅ ELO戦略選択 ✅ DYN1/DYN2動的クラス ❌ 結果: 複雑すぎ・性能不安定 ``` ### **第2世代: 単純な固定アプローチ (Phase 6.21)** ```c // 現在のシンプル設計 ✅ サイズ専用階層選択 (SACS-3) ✅ 固定サイズクラス ✅ Bridge Classes (ギャップ解消) ✅ TLS Active Slab ❌ 学習機能は削除 ✅ 結果: 安定 + mimalloc競合○ ``` --- ## 🏗️ SACS-3 アーキテクチャ詳細 ### **Size-Only Allocation Strategy** ```c // シンプルな分岐 if (size <= 1024) return tiny_alloc(size); else if (size < 2*1024*1024) return ace_alloc(size); else return big_cache_alloc(size); ``` ### **3階層設計の理論的根拠** | 階層 | サイズ範囲 | 技術選択 | 理由 | |------|-----------|----------|------| | **L0 Tiny** | ≤1KB | TLS Magazine | キャッシュ局所性最優先 | | **L1 ACE** | 1KB-2MB | 固定プール | 断片化と速度の最適バランス | | **L2 Big** | ≥2MB | BigCache+mmap | TLB効率とメモリ圧縮 | --- ## 🌉 Bridge Classesの設計 ### **なぜBridgeが必要か** ```c // 従来のギャップ問題 2KB,4KB,8KB,16KB,32KB,-------,64KB... // 30KBの穴 ^^^^^^^^^^^^^^^ # 35KBリクエスト→64KB(1.83倍!)× ``` ### **Bridgeによる解決** ```c // 2クラス追加でギャップ解消 2KB,4KB,8KB,16KB,32KB,40KB,52KB,64KB... ^^^^^^ ^^^^^^ # 35KB→40KB(1.14倍)○ ``` ### **設計決定のプロセス** 1. **動的DYN1試行**: 結局どこかに固定 2. **固定Bridge採用**: シンプルで確実 3. **断面分析**: 32-64KBが最大ギャップ 4. **2クラス追加**: 投資最小・効果最大 --- ## 🔧 TLS Active Slabの革新性 ### **従来の課題** ```c // 標準フリーリスト pthread_mutex_lock(); // 競合 발생 block = list_pop(); pthread_mutex_unlock(); // 毎回ロック ``` ### **TLS Active Slabの解決** ```c // 所有スレッド専用スラブ block = slab->bitmap_scan(); // ロックレス○ if (other_thread) { mpsc_push(remote_queue); // 非同期処理○ } ``` ### **3つのコンポーネント** 1. **TLS Magazine**: 最もホットなブロックをLIFOキャッシュ 2. **Active Slab**: 所有スレッドのみがbitmap更新 3. **MPSC Queue**: 他スレッドからのremote free受付 --- ## 📊 Bridge Classes性能分析 ### **内部断片化比較** | リクエスト | 従来 (W_MAX=1.60) | Bridge (W_MAX=1.30) | 改善率 | |-----------|------------------|---------------------|--------| | 35KB | 64KB (1.83倍) | 40KB (1.14倍) | **60%改善** | | 40KB | 64KB (1.60倍) | 40KB (1.00倍) | **100%改善** | | 50KB | 64KB (1.28倍) | 52KB (1.04倍) | **24%改善** | | 58KB | 64KB (1.10倍) | 64KB (1.10倍) | 0% | ### **メモリ効率** ``` 従来: 平均1.30倍断片化 Bridge: 平均1.08倍断片化 → 17%断片化削減 ``` --- ## 🧬 サイズクラス選定アルゴリズム ### **クラス決定ロジック** ```c static const size_t class_sizes[7] = { 2*1024, // 2KB 4*1024, // 4KB 8*1024, // 8KB 16*1024, // 16KB 32*1024, // 32KB 40960, // 40KB (Bridge) 53248 // 52KB (Bridge) }; static inline int size_to_class(size_t size) { if (size <= 32*1024) return size_class_lut[size/1024]; if (size <= 40*1024) return 5; // Bridge[0] if (size <= 52*1024) return 6; // Bridge[1] return -1; // Large Poolへ } ``` ### **LUT最適化** ```c // O(1)ルックアップテーブル (例) static const uint8_t tiny_class_table[33] = { 0,0,0,0, // 1-4KB → class 0 1,1,1,1, // 5-8KB → class 1 2,2,2,2, // 9-12KB → class 2 3,3,3,3, // 13-16KB → class 3 4,4,4,4 // 17-20KB → class 4 (32KB) }; ``` --- ## 🔄 スレッド安全性の設計 ### **階層的ロック戦略** ```c // Level 1: ロックレス (Tiny) // - TLS Magazine/Active Slab: 所有スレッドのみ // - MPSC Queue: lock-free操作 // Level 2: 細粒度ロック (ACE) // - 各クラス別mutex // - Page Registry: 256-way分割 // Level 3: 大域ロック (Big) // - mmap/munmapのみ // - 呼頻度が低い ``` ### **false sharing対策** ```c typedef struct ThreadLocalCache { CacheLine aligned_data; // 64-byte alignment char padding[64 - sizeof(CacheLine)]; // パディング } ThreadLocalCache; ``` --- ## 📈 性能測定フレームワーク ### **測定指標** ```c typedef struct { uint64_t alloc_count; // アロケーション回数 uint64_t free_count; // フリー回数 uint64_t total_bytes; // 総バイト数 uint64_t peak_rss; // RSSピーク uint64_t page_faults; // ページフォルト } HakmemStats; ``` ### **ベンチマーク戦略** ```bash # 1. マイクロベンチ (単一サイズ) ./bench_comprehensive --scenario tiny # 2. ストレスベンチ (スレッド競合) ./run_larson.sh -t 1,4,8 # 3. 実ワークロード (HTTPサーバー) HAKMEM_MODE=balanced LD_PRELOAD=./libhakmem.so nginx & ab -n 100000 -c 10 http://localhost/ ``` --- ## 🎯 設計トレードオフ ### **複雑性 vs 性能** | 設計選択 | 複雑さ | 性能 | メンテナンス性 | |----------|--------|------|--------------| | **動的学習** | 高 | 不安定 | 悪い | | **固定Bridge** | 低 | 安定 | 良い | ### **メモリ vs 速度** | 設計選択 | メモリ使用 | 速度 | 断片化 | |----------|-----------|------|--------| | **4倍CAP** | 78MB | 不変 | 低い | | **1倍CAP** | 24MB | -8%(1T)/+4%(4T) | やや高い | ### **結果**: 単純化の選択は正しかった --- ## 🔮 今後の改善可能性 ### **短期タイムライン** 1. **TLS Ring拡大**: CAP1倍→2倍で1T性能回復 2. **Background Refill**: ホットパス影響を最小化 3. **W_MAX最適化**: 動的調整無しで固定値改善 ### **中期タイムライン** 1. **NUMA対応**: ノードごとTLS分離 2. **ハイブリッドハイブリッド**: TLS + Central Pool混在 3. **サイズ分布適応**: 実測に基づく動的クラス選定 ### **原則**: 複雑性増大に注意 --- ## 📝 まとめ hakmemの設計は「**複雑な最適化より単純な確実性**」を実証したケーススタディです。 **成功の鍵**: 1. **Bridge Classes**: 最小投資で最大効果 2. **TLS Active Slab**: スレッド競合の根源的解決 3. **SACS-3**: シンプル3階層の安定性 **教訓**: 現実世界では、完璧な適応より堅実な実装が勝つ。 --- *このドキュメントは技術者向けの詳細設計解説です。より実用的なガイドは QUICK_REFERENCE.md を参照ください。*