Major Features: - Debug counter infrastructure for Refill Stage tracking - Free Pipeline counters (ss_local, ss_remote, tls_sll) - Diagnostic counters for early return analysis - Unified larson.sh benchmark runner with profiles - Phase 6-3 regression analysis documentation Bug Fixes: - Fix SuperSlab disabled by default (HAKMEM_TINY_USE_SUPERSLAB) - Fix profile variable naming consistency - Add .gitignore patterns for large files Performance: - Phase 6-3: 4.79 M ops/s (has OOM risk) - With SuperSlab: 3.13 M ops/s (+19% improvement) This is a clean repository without large log files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
6.9 KiB
6.9 KiB
hakmem Architecture Design - 設計思想と技術詳細
対象: 技術者・実装者・研究者
🧠 設計理念の進化
第1世代: 複雑な学習アプローチ (Phase 1-6.5)
// 過去の複雑設計
✅ Call-siteプロファイリング
✅ ACE (Agentic Context Engineering)
✅ UCB1バンディット学習
✅ ELO戦略選択
✅ DYN1/DYN2動的クラス
❌ 結果: 複雑すぎ・性能不安定
第2世代: 単純な固定アプローチ (Phase 6.21)
// 現在のシンプル設計
✅ サイズ専用階層選択 (SACS-3)
✅ 固定サイズクラス
✅ Bridge Classes (ギャップ解消)
✅ TLS Active Slab
❌ 学習機能は削除
✅ 結果: 安定 + mimalloc競合○
🏗️ SACS-3 アーキテクチャ詳細
Size-Only Allocation Strategy
// シンプルな分岐
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が必要か
// 従来のギャップ問題
2KB,4KB,8KB,16KB,32KB,-------,64KB... // 30KBの穴
^^^^^^^^^^^^^^^ # 35KBリクエスト→64KB(1.83倍!)×
Bridgeによる解決
// 2クラス追加でギャップ解消
2KB,4KB,8KB,16KB,32KB,40KB,52KB,64KB...
^^^^^^ ^^^^^^ # 35KB→40KB(1.14倍)○
設計決定のプロセス
- 動的DYN1試行: 結局どこかに固定
- 固定Bridge採用: シンプルで確実
- 断面分析: 32-64KBが最大ギャップ
- 2クラス追加: 投資最小・効果最大
🔧 TLS Active Slabの革新性
従来の課題
// 標準フリーリスト
pthread_mutex_lock(); // 競合 발생
block = list_pop();
pthread_mutex_unlock(); // 毎回ロック
TLS Active Slabの解決
// 所有スレッド専用スラブ
block = slab->bitmap_scan(); // ロックレス○
if (other_thread) {
mpsc_push(remote_queue); // 非同期処理○
}
3つのコンポーネント
- TLS Magazine: 最もホットなブロックをLIFOキャッシュ
- Active Slab: 所有スレッドのみがbitmap更新
- 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%断片化削減
🧬 サイズクラス選定アルゴリズム
クラス決定ロジック
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最適化
// 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)
};
🔄 スレッド安全性の設計
階層的ロック戦略
// 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対策
typedef struct ThreadLocalCache {
CacheLine aligned_data; // 64-byte alignment
char padding[64 - sizeof(CacheLine)]; // パディング
} ThreadLocalCache;
📈 性能測定フレームワーク
測定指標
typedef struct {
uint64_t alloc_count; // アロケーション回数
uint64_t free_count; // フリー回数
uint64_t total_bytes; // 総バイト数
uint64_t peak_rss; // RSSピーク
uint64_t page_faults; // ページフォルト
} HakmemStats;
ベンチマーク戦略
# 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) | やや高い |
結果: 単純化の選択は正しかった
🔮 今後の改善可能性
短期タイムライン
- TLS Ring拡大: CAP1倍→2倍で1T性能回復
- Background Refill: ホットパス影響を最小化
- W_MAX最適化: 動的調整無しで固定値改善
中期タイムライン
- NUMA対応: ノードごとTLS分離
- ハイブリッドハイブリッド: TLS + Central Pool混在
- サイズ分布適応: 実測に基づく動的クラス選定
原則: 複雑性増大に注意
📝 まとめ
hakmemの設計は「複雑な最適化より単純な確実性」を実証したケーススタディです。
成功の鍵:
- Bridge Classes: 最小投資で最大効果
- TLS Active Slab: スレッド競合の根源的解決
- SACS-3: シンプル3階層の安定性
教訓: 現実世界では、完璧な適応より堅実な実装が勝つ。
このドキュメントは技術者向けの詳細設計解説です。より実用的なガイドは QUICK_REFERENCE.md を参照ください。