Files
hakmem/perf_analysis_summary.md
Moe Charm (CI) 53bc92842b Add perf analysis reports from Task agent
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%)
2025-11-28 17:51:00 +09:00

265 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)
1. **malloc**: 26.10% (self) / 39.22% (children)
2. **free**: 19.47% (self) / 40.23% (children)
3. **shared_pool_acquire_slab**: 23.83% (children only)
4. **Page fault handling**: 25.55% (kernel time)
### 主要な発見
- **Page faults が顕著**: 25.55% が asm_exc_page_fault 経由
- `shared_pool_acquire_slab``__memset_avx2_unaligned_erms` → page fault
- `clear_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%)
**提案**:
1. **Lazy Initialization**: メタデータのゼロクリアを遅延化
- mmap(MAP_ANONYMOUS) は既にゼロページを返すため、明示的な memset は不要
- 4つの memset() 呼び出しlines 912-915を削除可能
- 推定効果: **10-15% throughput 向上**
2. **On-Demand Page Faulting**:
- MADV_DONTNEED または MADV_FREE を活用
- 実際に使用される slab だけ page fault を起こす
- 推定効果: **5-10% throughput 向上**
3. **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)
**提案**:
1. **Fast Path 統合**:
- 現状: smallmid → tiny → mid → ACE の順でチェック
- 提案: サイズレンジを統合して判定を1回に削減
```c
// 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 向上**
2. **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% と許容範囲だが、アクセス回数が多すぎる
**提案**:
1. **SuperSlab メタデータ構造の再配置**:
- Hot fieldsfreelist, used, capacityを先頭 64 bytes に集約
- Cold fieldsLRU, statisticsを末尾に移動
- `__attribute__((aligned(64)))` でキャッシュライン境界に整列
- 推定効果: **3-5% cache miss 削減**
2. **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
**提案**:
1. **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 削減**
2. **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 がある
**提案**:
1. **Registry First Policy**:
- mincore() の前に必ず SuperSlab registry を先にチェック
- Registry hit ならヘッダー読み取り不要
- 推定効果: **free() の 5-10% を高速化**
2. **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日)
1. SuperSlab memset 削除 (lines 912-915)
2. HAKMEM_DISABLE_MINCORE_CHECK=1 でビルド・測定
3. Front Gate に `__builtin_expect()` 追加
### Phase 2: 構造的改善 (1週間)
1. Front Gate dispatch table 実装
2. SuperSlab size を 512KB に変更
3. LTO 有効化
### Phase 3: 詳細分析 (2週間)
1. Valgrind/heaptrack でメモリプロファイリング
2. マルチスレッドベンチマーク追加
3. 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