Files
hakmem/docs/archive/PHASE_6.15_P0.2_INVESTIGATION.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

219 lines
6.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# Phase 6.15 P0.2 調査報告: clock_gettime 影響調査
**Date**: 2025-10-22
**Status**: ✅ 調査完了
**Goal**: Gemini診断clock_gettime がボトルネック)の検証
---
## 📊 **Executive Summary**
### **発見事実**
1.**軽量ベンチマーク64KB**: hakmem は system malloc と**ほぼ同等**+0.2%
2.**larsonベンチマーク8-1024B混合**: 非常に遅い0.62M ops/sec
3. ⚠️ **EVOLUTION無効化**: むしろ性能悪化1.05M → 0.62M、-41%
### **結論**
- **基本性能は正常**64KB allocations で system と同等)
- **小サイズ混合allocation** で mutex オーバーヘッドが顕在化
- **clock_gettime だけが原因ではない**(無効化で改善せず)
---
## 🔬 **テスト結果詳細**
### **Test 1: bench_allocators軽量、64KB固定**
#### **hakmem-baseline**
```bash
$ ./bench_allocators --allocator hakmem-baseline --scenario json --iterations 10000
allocator,scenario,iterations,avg_ns,soft_pf,hard_pf,rss_kb,ops_per_sec
hakmem-baseline,json,10000,214,17,0,0,4667120
```
#### **system malloc**
```bash
$ ./bench_allocators --allocator system --scenario json --iterations 10000
allocator,scenario,iterations,avg_ns,soft_pf,hard_pf,rss_kb,ops_per_sec
system,json,10000,213,17,0,0,4678406
```
#### **比較**
| Allocator | 平均時間 | ops/sec | vs system |
|-----------|---------|---------|-----------|
| hakmem | 214ns | 4.67M | +0.2% |
| system | 213ns | 4.68M | baseline |
**結論**: ✅ **64KB allocations では問題なし**
---
### **Test 2: larson重量、8-1024B混合**
#### **EVOLUTION有効時修正前**
```bash
# 実行: 以前のテスト結果
Throughput = 1,050,000 ops/sec (1.05M)
```
#### **EVOLUTION無効時#if 0**
```bash
$ cd /tmp/mimalloc-bench/bench/larson
$ env LD_PRELOAD=.../libhakmem.so ./larson 0 8 1024 10000 1 12345 1
[SiteRules] Initialized (MVP: 4-probe hash, capacity=2048)
Throughput = 623377 operations per second, relative time: 1604.167s.
[EVO] Initialized (policy=AUTO, freeze_sec=180, relearn_delta=20.00%)
Done sleeping...
[ELO] Initialized 12 strategies (thresholds: 512KB-32MB)
[Batch] Initialized (threshold=8 MB, min_size=64 KB)
[Pool] ERROR: Invalid magic in pool block!\n
```
#### **比較**
| 状態 | ops/sec | 実行時間 | エラー |
|------|---------|---------|-------|
| EVOLUTION有効 | 1.05M | 不明 | なし |
| EVOLUTION無効 | 0.62M | 1604秒(26分) | Pool ERROR ✅ |
**結論**: ❌ **EVOLUTION無効化で41%悪化** + エラー発生
---
## 🔍 **原因分析**
### **1. なぜEVOLUTION無効化で悪化したのか**
#### **仮説A: 初期化順序の問題**
出力ログの順序:
```
[SiteRules] Initialized ← 最初
Throughput = ... ← ベンチマーク実行ここでallocations発生
[EVO] Initialized ← 後から初期化!
[ELO] Initialized
[Batch] Initialized
[Pool] ERROR
```
**問題**: EVOが無効でも、`hak_init()` 内で各サブシステムが初期化される。しかし、EVOLUTION無効時は `g_cached_strategy_id` が初期化されない可能性。
#### **仮説B: Pool ERROR との関連**
```c
[Pool] ERROR: Invalid magic in pool block!\n
```
該当箇所を確認する必要がある(`hakmem_pool.c` の error メッセージ)。
---
### **2. larson vs bench_allocators の違い**
| 項目 | larson | bench_allocators |
|------|--------|------------------|
| サイズ範囲 | 8-1024B混合 | 64KB固定 |
| パターン | ランダム | 順次 |
| 実行時間 | 26分異常 | <1秒 |
| mutex競合 | 高頻度 | 低頻度 |
**結論**: **小サイズ・高頻度allocation で mutex オーバーヘッドが支配的**
---
### **3. Gemini診断の評価**
**Gemini仮説**: `clock_gettime()` がボトルネック1024回に1回
**検証結果**:
- `clock_gettime` は確かに高コスト数μs
- **しかし無効化で改善せず、むしろ悪化**
**新たな仮説**:
- mutex lock/unlock 自体のオーバーヘッドが主因
- 小サイズallocationsで頻度が高すぎる8-1024Bを10,000 chunks × rounds
---
## 🎯 **次のステップ**
### **Option A: EVOLUTION を元に戻す**(推奨)
**理由**:
- 無効化で悪化した
- Pool ERROR が発生
- 軽量ベンチマークでは問題なし
**実装**:
```c
// hakmem.c:378
#if HAKMEM_FEATURE_EVOLUTION // #if 0 から戻す
```
---
### **Option B: サンプリング頻度調整**(並行実施)
**現状**: 1024回に1回 `clock_gettime()`
**提案**: 環境変数で制御可能に
```c
// 環境変数: HAKMEM_EVO_SAMPLE
// 0 = disabled (default)
// 10 = 1024回に1回
// 16 = 65536回に1回
char* sample = getenv("HAKMEM_EVO_SAMPLE");
if (sample && atoi(sample) > 0) {
int freq = atoi(sample);
uint64_t mask = (1ULL << freq) - 1;
if ((atomic_fetch_add(&tick_counter, 1) & mask) == 0) {
clock_gettime(...);
}
}
```
**デフォルト**: 0無効で最速必要時のみ有効化
---
### **Option C: TLS 実装を優先**(最終手段)
P0での性能改善を諦めStep 3 (TLS) で根本解決
**理由**:
- 軽量ベンチマークでは既に system と同等
- larson の遅さは mutex 競合が主因
- TLS 95%+ のロック回避が可能
---
## 📝 **学んだこと**
1. **ベンチマーク選択の重要性**:
- larson は重すぎて調査に不向き
- 軽量ベンチマークで基本性能を先に確認すべき
2. **clock_gettime だけではない**:
- Gemini診断は部分的に正しいが主因ではなかった
- mutex lock/unlock の頻度が最大のボトルネック
3. **EVOLUTION の依存関係**:
- 無効化すると他の機能に影響
- 環境変数で制御する方が安全
---
## 🚀 **推奨アクション**
1. **EVOLUTION を元に戻す**5分
2. **環境変数制御を実装**デフォルト無効15分
3. **軽量ベンチマークで再テスト**1分
4. **larson は後回し**TLS実装後に再評価
---
**Status**: 調査完了次は Option A + B 実装へ