# Phase 6.15 P1.5 完了報告: TLSマガジン化 + 最適化 **Date**: 2025-10-22 **Status**: ✅ 完了 **Goal**: ChatGPT P1.5 実装(TLSマガジン化 + グローバルロック撤廃)の性能評価 --- ## 🎉 **Executive Summary** ### **最大の成果: string-builder が実行可能に!** 🎊 | Phase | string-builder | 結果 | |-------|----------------|------| | **P0** | ❌ タイムアウト | 実行不可 | | **P1** | ❌ タイムアウト | 実行不可 | | **P1.5** | **83ns/op (11.9M ops/sec)** ✅ | **動いた!** 🚀 | **mimalloc 比較**: 14ns/op (67.8M ops/sec) → **5.9倍遅い** が、実行可能になったことが重要 --- ## 📊 **ベンチマーク結果詳細** ### **Scenario 1: string-builder (8-64B, 小サイズ)** | Allocator | 平均時間 | ops/sec | vs system | vs mimalloc | |-----------|----------|---------|-----------|-------------| | **system** | 16ns | 62.3M | baseline | -8.1% | | **mimalloc** | 14ns | 67.8M | +8.8% | baseline | | **hakmem P0** | ❌ タイムアウト | ❌ | ❌ | ❌ | | **hakmem P1** | ❌ タイムアウト | ❌ | ❌ | ❌ | | **hakmem P1.5** | **83ns** | **11.9M** | **-81.0%** | **-82.4%** | **P0/P1 vs P1.5**: **実行不可 → 実行可能** ← **ブレークスルー!** 🎉 --- ### **Scenario 2: json (64KB, 中サイズ)** | Allocator | 平均時間 | ops/sec | vs system | vs mimalloc | |-----------|----------|---------|-----------|-------------| | **system** | 213ns | 4.68M | baseline | +24.6% | | **mimalloc** | 266ns | 3.76M | -19.9% | baseline | | **hakmem P0** | 291ns | 3.43M | -26.8% | -8.6% | | **hakmem P1** | 279ns | 3.58M | -23.6% | -4.7% | | **hakmem P1.5** | **280ns** | **3.56M** | **-23.9%** | **-5.3%** | **P1 vs P1.5**: ほぼ同等(+0.4% = 誤差範囲) --- ### **Scenario 3: mir (256KB, 大サイズ)** | Allocator | 平均時間 | ops/sec | vs system | vs mimalloc | |-----------|----------|---------|-----------|-------------| | **system** | 844ns | 1.18M | baseline | +14.1% | | **mimalloc** | 963ns | 1.04M | -12.4% | baseline | | **hakmem P0** | 888ns | 1.13M | -4.9% | +2.6% | | **hakmem P1** | 880ns | 1.14M | -4.1% | **+9.4%** ✅ | | **hakmem P1.5** | **911ns** | **1.10M** | **-7.4%** | **+5.7%** ✅ | **P1 vs P1.5**: 3.5%悪化(880ns → 911ns)⚠️ **mimalloc 比較**: 依然として **5.7%速い!** 🚀 --- ## 🔍 **P0 → P1 → P1.5 進化の軌跡** | Phase | 実装内容 | string-builder | json | mir | |-------|---------|----------------|------|-----| | **P0** | グローバルロック | ❌ タイムアウト | 291ns | 888ns | | **P1** | シャードロック化 | ❌ タイムアウト | 279ns (-4.1%) | 880ns (-0.9%) | | **P1.5** | **TLSマガジン化** | **83ns ✅** | 280ns (+0.4%) | 911ns (+3.5%) | --- ## 🛠️ **P1.5 実装詳細** (ChatGPT提供) ### **1. グローバルロック撤廃 + 再入ガード維持** - `hakmem.c`: malloc/free/calloc/realloc から `g_hakmem_lock` 削除 - `__thread g_hakmem_lock_depth` のみ残存(デッドロック回避) - 内部再入は `__libc_malloc` へフォールバック --- ### **2. L2 Pool (2-32KB) 細粒度ロック化** - `hakmem_pool.c`: クラス×シャードのパディングMutex (64B) - `nonempty_mask` を `atomic_uint_fast64_t` に変更(原子化) --- ### **3. L2.5 Pool (64KB-1MB) シャードロック化** - `hakmem_l25_pool.c`: シャードロック追加 - `nonempty_mask` 原子化(低コスト) --- ### **4. Tiny Pool (≤1KB) TLSマガジン化** ← **最重要!** **TLSマガジン構造**: ```c typedef struct { void* ptr; // Block pointer void* owner_slab; // Owner slab (lookup不要化) } TinyMagazineEntry; static __thread TinyMagazineEntry tls_magazine[TINY_MAGAZINE_CAP]; // CAP=256 static __thread int tls_mag_count = 0; ``` **メリット**: - ✅ **ロック不要** で push/pop - ✅ スピル時の lookup がゼロ(owner_slab 保持) - ✅ レジストリは読み取りロックフリー(登録/解除のみミューテックス) --- ### **5. 64KB ページ/バンドル mmap 化** - `hakmem_pool.c:164`: 64KBページ補充を mmap に変更(malloc輻輳回避) - `hakmem_l25_pool.c:186`: バンドル補充も mmap に変更 --- ### **6. BigCache 偽共有削減** - `hakmem_bigcache.c`: `BigCacheSlot` を 64B アライン(多コア衝突低減) --- ### **7. Site Rules 既定 OFF** - 環境変数で有効化: `HAKMEM_SITE_RULES=1` - `hakmem.c:279` でゲート(MT読み書き競合回避) --- ## 🏆 **mimalloc 比較まとめ** | Scenario | hakmem P1.5 | mimalloc | 差 | 勝敗 | |---------|-------------|----------|-----|------| | **string-builder (8-64B)** | 83ns | 14ns | **-82.4%** | ❌ 5.9倍遅い | | **json (64KB)** | 280ns | 266ns | **-5.3%** | ❌ 若干遅い | | **mir (256KB)** | 911ns | 963ns | **+5.7%** | ✅ **速い!** 🚀 | **結論**: 大サイズ(256KB)で mimalloc を上回る!小サイズは改善の余地あり。 --- ## 🎯 **成果と課題** ### ✅ **達成事項** 1. **string-builder が実行可能に!** 🎉 - P0/P1 でタイムアウト → P1.5 で 83ns/op - TLSマガジン化が効いた 2. **大サイズで mimalloc を上回る** - mir (256KB) で **5.7%速い** 🚀 - P1 の +9.4% から少し後退したが、依然として優位 3. **中サイズも健闘** - json (64KB) で mimalloc と -5.3%差(許容範囲) --- ### ❌ **課題** 1. **小サイズが依然として遅い** - string-builder で mimalloc の 5.9倍遅い(83ns vs 14ns) - TLSマガジンのオーバーヘッドが大きい可能性 2. **mir が P1 より悪化** - P1: 880ns → P1.5: 911ns (+3.5%悪化) - mmap 化の影響?要調査 --- ## 📈 **次のステップ** ### **Option A: 小サイズ最適化** (推奨) **目標**: string-builder を 83ns → 20-30ns に改善 **手順**: 1. TLSマガジンのキャパシティ調整(256 → 128?) 2. push/pop の実装見直し 3. owner_slab lookup の最適化 --- ### **Option B: mir 劣化調査** **目標**: P1 の 880ns に戻す **手順**: 1. mmap vs malloc のベンチマーク 2. L2.5 Pool のシャードロック影響確認 3. プロファイリング(perf) --- ### **Option C: mimalloc-bench 実行** (推奨) **目標**: 公式ベンチマークで性能確認 **ベンチマーク**: - larson (8-1024B mixed) - cache-scratch - cache-thrash - mstress **期待**: - 大サイズで mimalloc を上回る - 小サイズで改善の余地確認 --- ## 📝 **学んだこと** 1. **TLSマガジン化は有効** - タイムアウト → 実行可能 に改善 - ロック競合を回避 2. **トレードオフあり** - 小サイズで mimalloc より遅い - 大サイズで mimalloc より速い - 得意領域を活かす戦略が重要 3. **段階的最適化の重要性** - P0 → P1 → P1.5 で着実に改善 - 各段階で問題点を特定・解決 --- ## 🚀 **次のアクション** 1. ✅ **ドキュメント更新** (このファイル) 2. ⏭️ **CURRENT_TASK.md 更新** 3. ⏭️ **git commit (P1.5完了)** 4. ⏭️ **mimalloc-bench 実行** ← 次はこれ! --- **Status**: ✅ P1.5 完了、string-builder ブレークスルー達成! **Next**: mimalloc-bench で実力測定