Generated comprehensive performance analysis reports: - PERF_ANALYSIS_EXECUTIVE_SUMMARY.md: Executive summary with key findings - README_PERF_ANALYSIS.md: Index and navigation guide - perf_analysis_summary.md: Detailed bottleneck analysis Key findings: - HAKMEM: 55.7M ops/s vs System: 86.7M ops/s (-35.7%) - Top bottleneck: SuperSlab memset (23.83% CPU time) - Quick win: Remove redundant memset → +10-15% throughput - Phase 1 optimizations target: 65M ops/s (+17%)
9.4 KiB
HAKMEM アロケータ パフォーマンス分析レポート
1. 実行環境
- ベンチマーク: bench_random_mixed (1,000,000 ops, working set=256)
- プラットフォーム: Linux x86_64
- perf_event_paranoid: 1
2. パフォーマンス統計比較
HAKMEM アロケータ
Throughput: 55,705,335 ops/s
Time: 0.018s
Cycles: 78,648,007
Instructions: 167,028,675
IPC: 2.12
Cache References: 1,861,523
Cache Misses: 172,740 (9.28%)
Branches: 35,993,722
Branch Misses: 921,505 (2.56%)
System malloc (glibc)
Throughput: 86,683,664 ops/s (+55.6% faster)
Time: 0.012s
Cycles: 44,872,364 (-43.0% fewer cycles)
Instructions: 93,643,012 (-43.9% fewer instructions)
IPC: 2.09 (similar)
Cache References: 339,504 (-81.8% fewer)
Cache Misses: 45,009 (-73.9% fewer)
Branches: 16,572,153 (-53.9% fewer)
Branch Misses: 561,229 (-39.1% fewer)
3. ホットスポット分析
CPU時間消費 (Top Functions)
- malloc: 26.10% (self) / 39.22% (children)
- free: 19.47% (self) / 40.23% (children)
- shared_pool_acquire_slab: 23.83% (children only)
- Page fault handling: 25.55% (kernel time)
主要な発見
- Page faults が顕著: 25.55% が asm_exc_page_fault 経由
shared_pool_acquire_slab→__memset_avx2_unaligned_erms→ page faultclear_page_ermsが 4.46% を消費
- memset overhead:
__memset_avx2_unaligned_ermsが 6.41% - メモリ管理のオーバーヘッド: kernel の folio/page 管理が目立つ
4. ボトルネック特定
1. shared_pool_acquire_slab() の初期化コスト
- 問題: memset → page fault → kernel page allocation
- 影響: 23.83% の CPU 時間
- 原因: SuperSlab 獲得時の large memory clear (1MB/2MB)
2. 過剰なキャッシュ参照
- HAKMEM: 1,861,523 cache refs (system の 5.5倍)
- Cache miss率: 9.28% (system は 13.26% だがアクセス量が少ない)
- 分析: データ構造のメモリフットプリントが大きい
3. 分岐数の多さ
- HAKMEM: 35,993,722 branches (system の 2.2倍)
- Branch miss率: 2.56% (system は 3.39%)
- 分析: 複雑な分岐ロジック (Front Gate, domain routing, etc.)
4. 命令数の多さ
- HAKMEM: 167M instructions (system の 1.8倍)
- 分析: 多層的なアロケーション戦略 (Tiny/Mid/ACE/BigCache)
5. 最適化提案(優先度順)
優先度1: SuperSlab 初期化の遅延化・削減
問題: shared_pool_acquire_slab() で 23.83% の CPU 時間を消費
- memset による 1MB-2MB のゼロクリア
- Page fault による kernel page allocation (clear_page_erms: 4.46%)
提案:
-
Lazy Initialization: メタデータのゼロクリアを遅延化
- mmap(MAP_ANONYMOUS) は既にゼロページを返すため、明示的な memset は不要
- 4つの memset() 呼び出し(lines 912-915)を削除可能
- 推定効果: 10-15% throughput 向上
-
On-Demand Page Faulting:
- MADV_DONTNEED または MADV_FREE を活用
- 実際に使用される slab だけ page fault を起こす
- 推定効果: 5-10% throughput 向上
-
SuperSlab Size 調整:
- 現状: 1MB (lg=20) or 2MB (lg=21)
- 提案: 512KB (lg=19) or 256KB (lg=18) をデフォルトに
- 推定効果: 初期化コスト 50-75% 削減
実装箇所: /mnt/workdisk/public_share/hakmem/core/hakmem_tiny_superslab.c:912-915
優先度2: Front Gate 分岐最適化
問題: 35,993,722 branches (system の 2.2倍)
- Branch miss率は良好 (2.56%) だが絶対数が多い
- malloc/free の多層ルーティング (Tiny/Mid/ACE/BigCache)
提案:
-
Fast Path 統合:
- 現状: smallmid → tiny → mid → ACE の順でチェック
- 提案: サイズレンジを統合して判定を1回に削減
// Before: 4 separate checks if (smallmid_is_in_range(size)) { ... } if (size <= tiny_get_max_size()) { ... } if (mid_is_in_range(size)) { ... } if (size < threshold) { ... } // After: Single dispatch table void* (*allocator)(size_t) = size_dispatch_table[size >> 8]; return allocator(size);- 推定効果: 5-8% throughput 向上
-
Likely/Unlikely Hints 追加:
/mnt/workdisk/public_share/hakmem/core/box/hak_alloc_api.inc.h:43-78- 使用頻度が高い Tiny path に
__builtin_expect() - 推定効果: 2-3% throughput 向上
優先度3: キャッシュライン最適化
問題: 1,861,523 cache refs (system の 5.5倍)
- Cache miss率は 9.28% と許容範囲だが、アクセス回数が多すぎる
提案:
-
SuperSlab メタデータ構造の再配置:
- Hot fields(freelist, used, capacity)を先頭 64 bytes に集約
- Cold fields(LRU, statistics)を末尾に移動
__attribute__((aligned(64)))でキャッシュライン境界に整列- 推定効果: 3-5% cache miss 削減
-
TLS Hot Slot の積極活用:
- 現状: Stage 0 (L0 reuse) は既に実装済み (lines 802-832)
- 提案: L0 hit rate をモニタリングし、閾値調整
- ENV:
HAKMEM_SS_L0_CAPACITYでキャッシュサイズ拡大 - 推定効果: Stage 1-3 の呼び出し 20-30% 削減
優先度4: インライン化の最適化
問題: 167M instructions (system の 1.8倍)
- 多層の関数呼び出しによる overhead
提案:
-
Critical Path のインライン化:
fg_classify_domain()- 既に static inline?hak_tiny_free_fast_v2()- 既に always_inline 化されているsmallmid_is_in_range()/mid_is_in_range()を強制インライン- 推定効果: 2-4% call overhead 削減
-
LTO (Link Time Optimization) の有効化:
-flto -fwhole-programでコンパイル- クロスモジュールのインライン化が可能に
- 推定効果: 5-8% code size 削減、2-3% throughput 向上
優先度5: mincore() 呼び出しの削減
問題: free() 内の mincore() によるシステムコール overhead
/mnt/workdisk/public_share/hakmem/core/box/hak_free_api.inc.h:224-272- TLS page cache で緩和されているが、まだ overhead がある
提案:
-
Registry First Policy:
- mincore() の前に必ず SuperSlab registry を先にチェック
- Registry hit ならヘッダー読み取り不要
- 推定効果: free() の 5-10% を高速化
-
Compile-Time Option:
HAKMEM_DISABLE_MINCORE_CHECK=1を production default に- Invalid pointer は極稀なので、クラッシュリスクは許容範囲
- 推定効果: free() の 10-15% を高速化
6. 実測効果の予測
楽観的シナリオ(全提案を実装)
| 最適化項目 | 予測効果 |
|---|---|
| SuperSlab lazy init | +15% |
| Front Gate 統合 | +8% |
| Cache line 最適化 | +5% |
| Inline + LTO | +5% |
| mincore 削減 | +8% |
| 合計 | +41% (複合効果を考慮) |
目標スループット: 55M → 77M ops/s (system 86M の 89%)
保守的シナリオ(優先度1-2のみ実装)
| 最適化項目 | 予測効果 |
|---|---|
| SuperSlab lazy init | +12% |
| Front Gate 統合 | +5% |
| 合計 | +17% |
目標スループット: 55M → 65M ops/s (system 86M の 75%)
7. 追加分析が必要な項目
7.1 メモリフットプリント
- 課題: Cache refs が 5.5倍 → データ構造サイズが大きい可能性
- 調査:
sizeof(SuperSlab),sizeof(TinySlabMeta)の確認 - ツール: Valgrind massif, heaptrack
7.2 マルチスレッド性能
- 課題: 現在のベンチマークはシングルスレッド
- 調査: pthread 環境での lock contention
- ツール:
perf record -e lock:contention_begin
7.3 Workload 別の最適戦略
- 課題: random_mixed 以外のパターン(sequential, burst, etc.)
- 調査: ELO strategy の adaptive 効果測定
- ベンチマーク: bench_comprehensive の全パターン実行
8. 次のステップ
Phase 1: Quick Wins (1-2日)
- SuperSlab memset 削除 (lines 912-915)
- HAKMEM_DISABLE_MINCORE_CHECK=1 でビルド・測定
- Front Gate に
__builtin_expect()追加
Phase 2: 構造的改善 (1週間)
- Front Gate dispatch table 実装
- SuperSlab size を 512KB に変更
- LTO 有効化
Phase 3: 詳細分析 (2週間)
- Valgrind/heaptrack でメモリプロファイリング
- マルチスレッドベンチマーク追加
- Workload 別の最適化
9. 参考データ
ファイルパス
- perf データ:
/mnt/workdisk/public_share/hakmem/perf.data - ホットスポットレポート:
/mnt/workdisk/public_share/hakmem/perf_hakmem_hotspots.txt - 統計データ:
/mnt/workdisk/public_share/hakmem/perf_hakmem_stats.txt - コールグラフ:
/mnt/workdisk/public_share/hakmem/perf_hakmem_callgraph.txt
重要なソースファイル
- Alloc API:
/mnt/workdisk/public_share/hakmem/core/box/hak_alloc_api.inc.h - Free API:
/mnt/workdisk/public_share/hakmem/core/box/hak_free_api.inc.h - SuperSlab:
/mnt/workdisk/public_share/hakmem/core/hakmem_tiny_superslab.c - Shared Pool:
/mnt/workdisk/public_share/hakmem/core/hakmem_shared_pool.c
レポート生成日: 2025-11-28
分析対象: HAKMEM allocator (commit 0ce20bb83)
ベンチマーク: bench_random_mixed_hakmem 1000000 256 42