Files
hakmem/docs/design/ARCHITECTURE_DESIGN.md
Moe Charm (CI) 52386401b3 Debug Counters Implementation - Clean History
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>
2025-11-05 12:31:14 +09:00

6.9 KiB
Raw Blame History

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...
           ^^^^^^ ^^^^^^  # 35KB40KB(1.14)

設計決定のプロセス

  1. 動的DYN1試行: 結局どこかに固定
  2. 固定Bridge採用: シンプルで確実
  3. 断面分析: 32-64KBが最大ギャップ
  4. 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つのコンポーネント

  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%断片化削減

🧬 サイズクラス選定アルゴリズム

クラス決定ロジック

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) やや高い

結果: 単純化の選択は正しかった


🔮 今後の改善可能性

短期タイムライン

  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 を参照ください。