213 lines
5.5 KiB
Markdown
213 lines
5.5 KiB
Markdown
|
|
# HAKMEM アロケータ パフォーマンス分析 - エグゼクティブサマリー
|
||
|
|
|
||
|
|
## 📊 現状評価
|
||
|
|
|
||
|
|
### スループット比較
|
||
|
|
- **HAKMEM**: 55.7M ops/s
|
||
|
|
- **System (glibc)**: 86.7M ops/s
|
||
|
|
- **差分**: -35.7% (HAKMEM が遅い)
|
||
|
|
|
||
|
|
### 効率指標
|
||
|
|
✅ **良好な指標**:
|
||
|
|
- IPC (Instructions Per Cycle): 2.12 vs 2.09 (HAKMEM が若干上)
|
||
|
|
- Branch Miss率: 2.56% vs 3.39% (HAKMEM が良好)
|
||
|
|
- Cache Miss率: 9.28% vs 13.26% (HAKMEM が良好)
|
||
|
|
|
||
|
|
❌ **問題のある指標**:
|
||
|
|
- Instructions: 167M vs 94M (+78%, HAKMEM が1.8倍多い)
|
||
|
|
- Cache References: 1.86M vs 340K (+448%, HAKMEM が5.5倍多い)
|
||
|
|
- Branches: 36M vs 16.6M (+117%, HAKMEM が2.2倍多い)
|
||
|
|
|
||
|
|
### 🔍 本質的な問題
|
||
|
|
**HAKMEM は「仕事の質」は高いが「仕事の量」が多すぎる**
|
||
|
|
- 分岐予測・キャッシュ効率は優秀
|
||
|
|
- しかし、不要な処理が多く、全体のスループットを低下させている
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔥 トップ3ボトルネック
|
||
|
|
|
||
|
|
### 1位: SuperSlab 初期化の Page Fault (23.83% CPU時間)
|
||
|
|
**症状**:
|
||
|
|
```
|
||
|
|
shared_pool_acquire_slab()
|
||
|
|
→ memset(1MB-2MB)
|
||
|
|
→ page fault
|
||
|
|
→ kernel clear_page_erms (4.46%)
|
||
|
|
```
|
||
|
|
|
||
|
|
**原因**:
|
||
|
|
- SuperSlab 獲得時に 1MB-2MB のメモリをゼロクリア
|
||
|
|
- mmap は既にゼロページを返すのに、4つの memset() を実行
|
||
|
|
- Lines 912-915 in hakmem_tiny_superslab.c
|
||
|
|
|
||
|
|
**即効性のある対策**:
|
||
|
|
```bash
|
||
|
|
# 4つの memset() をコメントアウト
|
||
|
|
# 理由: mmap(MAP_ANONYMOUS) は既にゼロ初期化されている
|
||
|
|
# 推定効果: +10-15% throughput
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2位: 多層分岐ルーティング (36M branches, 2.2倍)
|
||
|
|
**症状**:
|
||
|
|
- malloc 1回あたり 36 branches (system は 16.6)
|
||
|
|
- smallmid → tiny → mid → ACE の順次チェック
|
||
|
|
|
||
|
|
**原因**:
|
||
|
|
- Front Gate の domain 分類が複雑
|
||
|
|
- サイズレンジごとに個別判定
|
||
|
|
|
||
|
|
**対策**:
|
||
|
|
```c
|
||
|
|
// Dispatch table で一発判定
|
||
|
|
void* (*allocator)(size_t) = size_dispatch_table[size >> 8];
|
||
|
|
return allocator(size);
|
||
|
|
```
|
||
|
|
**推定効果**: +5-8% throughput
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3位: 過剰なキャッシュアクセス (1.86M refs, 5.5倍)
|
||
|
|
**症状**:
|
||
|
|
- Cache references が system の 5.5倍
|
||
|
|
- Miss率は良好だが、アクセス回数自体が多すぎる
|
||
|
|
|
||
|
|
**原因**:
|
||
|
|
- SuperSlab メタデータが大きい
|
||
|
|
- Hot/Cold フィールドが混在
|
||
|
|
|
||
|
|
**対策**:
|
||
|
|
```c
|
||
|
|
// Hot fields を先頭64バイトに集約
|
||
|
|
struct SuperSlab {
|
||
|
|
// Cache line 0 (HOT)
|
||
|
|
uint64_t magic;
|
||
|
|
void* freelist;
|
||
|
|
uint32_t used;
|
||
|
|
uint32_t capacity;
|
||
|
|
// ...
|
||
|
|
|
||
|
|
// Cache line N (COLD)
|
||
|
|
uint64_t last_used_ns;
|
||
|
|
uint64_t generation;
|
||
|
|
// ...
|
||
|
|
} __attribute__((aligned(64)));
|
||
|
|
```
|
||
|
|
**推定効果**: +3-5% cache efficiency
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 最適化ロードマップ
|
||
|
|
|
||
|
|
### Phase 1: Quick Wins (1-2日, +17% 目標)
|
||
|
|
1. ✅ **memset 削除** (lines 912-915)
|
||
|
|
- 4つの memset() をコメントアウト
|
||
|
|
- 効果: +12%
|
||
|
|
|
||
|
|
2. ✅ **Front Gate に `__builtin_expect()` 追加**
|
||
|
|
- Tiny path を likely に設定
|
||
|
|
- 効果: +2-3%
|
||
|
|
|
||
|
|
3. ✅ **HAKMEM_DISABLE_MINCORE_CHECK=1 でビルド**
|
||
|
|
- mincore() syscall を削減
|
||
|
|
- 効果: +2-3%
|
||
|
|
|
||
|
|
**Phase 1 合計**: 55M → **65M ops/s** (system の 75%)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Phase 2: 構造的改善 (1週間, +24% 追加目標)
|
||
|
|
1. **Front Gate dispatch table 実装**
|
||
|
|
- サイズ → アロケータの直接マッピング
|
||
|
|
- 効果: +5-8%
|
||
|
|
|
||
|
|
2. **SuperSlab サイズを 512KB に縮小**
|
||
|
|
- 初期化コストを半減
|
||
|
|
- 効果: +5-7%
|
||
|
|
|
||
|
|
3. **LTO 有効化**
|
||
|
|
- `-flto -fwhole-program`
|
||
|
|
- 効果: +3-5%
|
||
|
|
|
||
|
|
4. **Cache line 最適化**
|
||
|
|
- SuperSlab 構造体の再配置
|
||
|
|
- 効果: +3-5%
|
||
|
|
|
||
|
|
**Phase 2 合計**: 65M → **77M ops/s** (system の 89%)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Phase 3: 詳細分析 (2週間)
|
||
|
|
- Valgrind/heaptrack でメモリプロファイリング
|
||
|
|
- マルチスレッドベンチマーク
|
||
|
|
- Workload 別の最適化
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📈 予測効果まとめ
|
||
|
|
|
||
|
|
| シナリオ | スループット | System比 | 実装期間 |
|
||
|
|
|---------|------------|---------|---------|
|
||
|
|
| 現状 | 55.7M ops/s | 64.3% | - |
|
||
|
|
| Phase 1 (保守的) | 65.2M ops/s | 75.2% | 1-2日 |
|
||
|
|
| Phase 2 (楽観的) | 77.5M ops/s | 89.4% | 1週間 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🛠️ すぐに試せるコマンド
|
||
|
|
|
||
|
|
### 1. memset 削除版のビルド
|
||
|
|
```bash
|
||
|
|
cd /mnt/workdisk/public_share/hakmem
|
||
|
|
# Backup
|
||
|
|
cp core/hakmem_tiny_superslab.c core/hakmem_tiny_superslab.c.bak
|
||
|
|
|
||
|
|
# Edit lines 912-915 (comment out memset)
|
||
|
|
sed -i '912,915s/^/\/\/ PERF_OPT: /' core/hakmem_tiny_superslab.c
|
||
|
|
|
||
|
|
# Rebuild
|
||
|
|
make clean && make
|
||
|
|
|
||
|
|
# Benchmark
|
||
|
|
./bench_random_mixed_hakmem 1000000 256 42
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. mincore 無効化版のビルド
|
||
|
|
```bash
|
||
|
|
make clean
|
||
|
|
make CFLAGS="-DHAKMEM_DISABLE_MINCORE_CHECK=1"
|
||
|
|
./bench_random_mixed_hakmem 1000000 256 42
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. 両方を適用
|
||
|
|
```bash
|
||
|
|
make clean
|
||
|
|
make CFLAGS="-DHAKMEM_DISABLE_MINCORE_CHECK=1"
|
||
|
|
# + memset コメントアウト済み
|
||
|
|
./bench_random_mixed_hakmem 1000000 256 42
|
||
|
|
```
|
||
|
|
|
||
|
|
**期待される結果**: 55M → **63-67M ops/s** (+13-20%)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📁 生成ファイル一覧
|
||
|
|
|
||
|
|
1. **perf_analysis_summary.md** - 詳細分析レポート (このファイル)
|
||
|
|
2. **perf_comparison_chart.txt** - 視覚的比較チャート
|
||
|
|
3. **perf_hakmem_hotspots.txt** - ホットスポット詳細
|
||
|
|
4. **perf_hakmem_stats.txt** - HAKMEM 統計
|
||
|
|
5. **perf_system_stats.txt** - System malloc 統計
|
||
|
|
6. **perf_hakmem_callgraph.txt** - コールグラフ
|
||
|
|
7. **perf_annotate_malloc.txt** - malloc 関数のアノテーション
|
||
|
|
8. **PERF_ANALYSIS_EXECUTIVE_SUMMARY.md** - エグゼクティブサマリー
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**分析完了日時**: 2025-11-28
|
||
|
|
**使用ツール**: perf record/stat/report
|
||
|
|
**ベンチマーク**: bench_random_mixed (1M ops, WS=256)
|
||
|
|
**分析者**: Claude Code (Sonnet 4.5)
|