320 lines
8.1 KiB
Markdown
320 lines
8.1 KiB
Markdown
|
|
# hakmem_tiny_free.inc 構造分析 - クイックサマリー
|
||
|
|
|
||
|
|
## ファイル概要
|
||
|
|
|
||
|
|
**hakmem_tiny_free.inc** は HAKMEM メモリアロケータのメイン Free パスを実装する大規模ファイル
|
||
|
|
|
||
|
|
| 統計 | 値 |
|
||
|
|
|------|-----|
|
||
|
|
| **総行数** | 1,711 |
|
||
|
|
| **実コード行** | 1,348 (78.7%) |
|
||
|
|
| **関数数** | 10個 |
|
||
|
|
| **最大関数** | `hak_tiny_free_with_slab()` - 558行 |
|
||
|
|
| **複雑度** | CC 28 (CRITICAL) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 主要責務ベークダウン
|
||
|
|
|
||
|
|
```
|
||
|
|
hak_tiny_free_with_slab (558行, 34.2%) ← HOTTEST - CC 28
|
||
|
|
├─ SuperSlab mode handling (64行)
|
||
|
|
├─ Same-thread TLS push (72行)
|
||
|
|
└─ Magazine/SLL/Publisher paths (413行) ← 複雑でテスト困難
|
||
|
|
|
||
|
|
hak_tiny_free_superslab (305行, 18.7%) ← CRITICAL PATH - CC 16
|
||
|
|
├─ Validation & safety checks (30行)
|
||
|
|
├─ Same-thread freelist push (79行)
|
||
|
|
└─ Remote/cross-thread queue (159行)
|
||
|
|
|
||
|
|
superslab_refill (308行, 24.1%) ← OPTIMIZATION TARGET - CC 18
|
||
|
|
├─ Mid-size simple refill (36行)
|
||
|
|
├─ SuperSlab adoption (163行)
|
||
|
|
└─ Fresh allocation (70行)
|
||
|
|
|
||
|
|
hak_tiny_free (135行, 8.3%) ← ENTRY POINT - CC 12
|
||
|
|
├─ Mode selection (BENCH, ULTRA, NORMAL)
|
||
|
|
└─ Class resolution & dispatch
|
||
|
|
|
||
|
|
Other (127行, 7.7%)
|
||
|
|
├─ Helper functions (65行) - drain, remote guard
|
||
|
|
├─ SuperSlab alloc helpers (84行)
|
||
|
|
└─ Shutdown (30行)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 関数リスト(重要度順)
|
||
|
|
|
||
|
|
### 🔴 CRITICAL (テスト困難、複雑)
|
||
|
|
|
||
|
|
1. **hak_tiny_free_with_slab()** (558行)
|
||
|
|
- 複雑度: CC 28 ← **NEEDS REFACTORING**
|
||
|
|
- 責務: Free path の main router
|
||
|
|
- 課題: Magazine/SLL/Publisher が混在
|
||
|
|
|
||
|
|
2. **superslab_refill()** (308行)
|
||
|
|
- 複雑度: CC 18
|
||
|
|
- 責務: SuperSlab adoption & allocation
|
||
|
|
- 最適化: P0 で O(n) → O(1) 化予定
|
||
|
|
|
||
|
|
3. **hak_tiny_free_superslab()** (305行)
|
||
|
|
- 複雑度: CC 16
|
||
|
|
- 責務: SuperSlab free (same/remote)
|
||
|
|
- 課題: Remote queue sentinel validation が複雑
|
||
|
|
|
||
|
|
### 🟡 HIGH (重要だが理解可能)
|
||
|
|
|
||
|
|
4. **superslab_alloc_from_slab()** (84行)
|
||
|
|
- 複雑度: CC 4
|
||
|
|
- 責務: Single slab block allocation
|
||
|
|
|
||
|
|
5. **hak_tiny_alloc_superslab()** (151行)
|
||
|
|
- 複雑度: CC ~8
|
||
|
|
- 責務: SuperSlab-based allocation entry
|
||
|
|
|
||
|
|
6. **hak_tiny_free()** (135行)
|
||
|
|
- 複雑度: CC 12
|
||
|
|
- 責務: Global free entry point (routing only)
|
||
|
|
|
||
|
|
### 🟢 LOW (シンプル)
|
||
|
|
|
||
|
|
7. **tiny_drain_to_sll_budget()** (10行) - ENV config
|
||
|
|
8. **tiny_drain_freelist_to_sll_once()** (16行) - SLL splicing
|
||
|
|
9. **tiny_remote_queue_contains_guard()** (21行) - Duplicate detection
|
||
|
|
10. **hak_tiny_shutdown()** (30行) - Cleanup
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 主要な複雑性源
|
||
|
|
|
||
|
|
### 1. `hak_tiny_free_with_slab()` の複雑度 (CC 28)
|
||
|
|
|
||
|
|
```c
|
||
|
|
if (!slab) {
|
||
|
|
// SuperSlab path (64行)
|
||
|
|
// ├─ SuperSlab lookup
|
||
|
|
// ├─ Validation (HAKMEM_SAFE_FREE)
|
||
|
|
// └─ if remote → hak_tiny_free_superslab()
|
||
|
|
}
|
||
|
|
// 複数の TLS キャッシュパス (72行)
|
||
|
|
// ├─ Fast path (g_fast_enable)
|
||
|
|
// ├─ TLS List (g_tls_list_enable)
|
||
|
|
// ├─ HotMag (g_hotmag_enable)
|
||
|
|
// └─ ...
|
||
|
|
// Magazine/SLL/Publisher paths (413行)
|
||
|
|
// ├─ TinyQuickSlot?
|
||
|
|
// ├─ TLS SLL?
|
||
|
|
// ├─ Magazine?
|
||
|
|
// ├─ Background spill?
|
||
|
|
// ├─ SuperRegistry spill?
|
||
|
|
// └─ Publisher fallback?
|
||
|
|
```
|
||
|
|
|
||
|
|
**課題:** Policy cascade (複数パスの判定フロー)が線形に追加されている
|
||
|
|
|
||
|
|
### 2. `superslab_refill()` の複雑度 (CC 18)
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─ Mid-size simple refill (class >= 4)?
|
||
|
|
├─ SuperSlab adoption?
|
||
|
|
│ ├─ Cool-down check
|
||
|
|
│ ├─ First-fit or Best-fit scoring
|
||
|
|
│ ├─ Slab acquisition
|
||
|
|
│ └─ Binding
|
||
|
|
└─ Fresh allocation
|
||
|
|
├─ SuperSlab allocate
|
||
|
|
└─ Refcount management
|
||
|
|
```
|
||
|
|
|
||
|
|
**課題:** Adoption vs allocation decision が複雑 (Future P0 optimization target)
|
||
|
|
|
||
|
|
### 3. `hak_tiny_free_superslab()` の複雑度 (CC 16)
|
||
|
|
|
||
|
|
```
|
||
|
|
├─ Validation (bounds, magic, size_class)
|
||
|
|
├─ if (same-thread)
|
||
|
|
│ ├─ Direct freelist push
|
||
|
|
│ ├─ remote guard check
|
||
|
|
│ └─ MidTC integration
|
||
|
|
└─ else (remote)
|
||
|
|
├─ Remote queue enqueue
|
||
|
|
├─ Sentinel validation
|
||
|
|
└─ Bulk refill coordination
|
||
|
|
```
|
||
|
|
|
||
|
|
**課題:** Same vs remote path が大きく分岐
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 分割提案(優先度順)
|
||
|
|
|
||
|
|
### Phase 1: Magazine/SLL を分離 (413行)
|
||
|
|
|
||
|
|
**新ファイル:** `tiny_free_magazine.inc.h`
|
||
|
|
|
||
|
|
**メリット:**
|
||
|
|
- Policy cascade を独立ファイルに隔離
|
||
|
|
- Magazine は environment-based (on/off可能)
|
||
|
|
- テスト時に mock 可能
|
||
|
|
- スパイル改善時の影響を限定
|
||
|
|
|
||
|
|
```
|
||
|
|
Before: hak_tiny_free_with_slab() CC 28 → 413行
|
||
|
|
After: hak_tiny_free_with_slab() CC ~8
|
||
|
|
+ tiny_free_magazine.inc.h CC ~10
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Phase 2: SuperSlab allocation を分離 (394行)
|
||
|
|
|
||
|
|
**新ファイル:** `tiny_superslab_alloc.inc.h`
|
||
|
|
|
||
|
|
**含める関数:**
|
||
|
|
- `superslab_refill()` (308行)
|
||
|
|
- `superslab_alloc_from_slab()` (84行)
|
||
|
|
- `hak_tiny_alloc_superslab()` (151行)
|
||
|
|
- Adoption helpers
|
||
|
|
|
||
|
|
**メリット:**
|
||
|
|
- Allocation は free と直交
|
||
|
|
- P0 optimization (O(n)→O(1)) に集中
|
||
|
|
- Registry logic を明確化
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Phase 3: SuperSlab free を分離 (305行)
|
||
|
|
|
||
|
|
**新ファイル:** `tiny_superslab_free.inc.h`
|
||
|
|
|
||
|
|
**含める関数:**
|
||
|
|
- `hak_tiny_free_superslab()` (305行)
|
||
|
|
- Remote queue management
|
||
|
|
- Sentinel validation
|
||
|
|
|
||
|
|
**メリット:**
|
||
|
|
- Remote queue logic は pure
|
||
|
|
- Cross-thread free を focused に
|
||
|
|
- Debugging (ROUTE_MARK) が簡単
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 分割後の構成
|
||
|
|
|
||
|
|
### Current (1ファイル)
|
||
|
|
```
|
||
|
|
hakmem_tiny_free.inc (1,711行)
|
||
|
|
├─ Helpers & includes
|
||
|
|
├─ hak_tiny_free_with_slab (558行) ← MONOLITH
|
||
|
|
├─ SuperSlab alloc/refill (394行)
|
||
|
|
├─ SuperSlab free (305行)
|
||
|
|
├─ Main entry (135行)
|
||
|
|
└─ Shutdown (30行)
|
||
|
|
```
|
||
|
|
|
||
|
|
### After refactoring (4ファイル)
|
||
|
|
```
|
||
|
|
hakmem_tiny_free.inc (450行) ← THIN ROUTER
|
||
|
|
├─ Helpers & includes
|
||
|
|
├─ hak_tiny_free (dispatch only)
|
||
|
|
├─ hak_tiny_shutdown
|
||
|
|
└─ #include directives (3個)
|
||
|
|
|
||
|
|
tiny_free_magazine.inc.h (400行)
|
||
|
|
├─ TinyQuickSlot
|
||
|
|
├─ TLS SLL push
|
||
|
|
├─ Magazine push/spill
|
||
|
|
├─ Background spill
|
||
|
|
└─ Publisher fallback
|
||
|
|
|
||
|
|
tiny_superslab_alloc.inc.h (380行) ← P0 OPTIMIZATION HERE
|
||
|
|
├─ superslab_refill (with nonempty_mask O(n)→O(1))
|
||
|
|
├─ superslab_alloc_from_slab
|
||
|
|
└─ hak_tiny_alloc_superslab
|
||
|
|
|
||
|
|
tiny_superslab_free.inc.h (290行)
|
||
|
|
├─ hak_tiny_free_superslab
|
||
|
|
├─ Remote queue management
|
||
|
|
└─ Sentinel validation
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 実装手順
|
||
|
|
|
||
|
|
### Step 1: バックアップ
|
||
|
|
```bash
|
||
|
|
cp core/hakmem_tiny_free.inc core/hakmem_tiny_free.inc.bak
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 2-4: 3ファイルに分割
|
||
|
|
```
|
||
|
|
Lines 208-620 → core/tiny_free_magazine.inc.h
|
||
|
|
Lines 626-1019 → core/tiny_superslab_alloc.inc.h
|
||
|
|
Lines 1171-1475 → core/tiny_superslab_free.inc.h
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 5: Makefile update
|
||
|
|
```makefile
|
||
|
|
hakmem_tiny_free.inc は #include で 3ファイルを参照
|
||
|
|
→ dependency に追加
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 6: 検証
|
||
|
|
```bash
|
||
|
|
make clean && make
|
||
|
|
./larson_hakmem 2 8 128 1024 1 12345 4
|
||
|
|
# スコア変化なし を確認
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 分割前後の改善指標
|
||
|
|
|
||
|
|
| 指標 | Before | After | 改善 |
|
||
|
|
|------|--------|-------|------|
|
||
|
|
| **ファイル数** | 1 | 4 | +300% (関心分離) |
|
||
|
|
| **avg CC** | 14.4 | 8.2 | **-43%** |
|
||
|
|
| **max CC** | 28 | 16 | **-43%** |
|
||
|
|
| **max func size** | 558行 | 308行 | **-45%** |
|
||
|
|
| **理解難易度** | ★★★★☆ | ★★★☆☆ | **-1段階** |
|
||
|
|
| **テスト容易性** | ★★☆☆☆ | ★★★★☆ | **+2段階** |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 関連最適化
|
||
|
|
|
||
|
|
### P0 Optimization (Already in CLAUDE.md)
|
||
|
|
- **File:** `tiny_superslab_alloc.inc.h` (after split)
|
||
|
|
- **Location:** `superslab_refill()` lines ~785-947
|
||
|
|
- **Optimization:** O(n) linear scan → O(1) ctz using `nonempty_mask`
|
||
|
|
- **Expected:** CPU 29.47% → 25.89% (-12%)
|
||
|
|
|
||
|
|
### P1 Opportunities (After split)
|
||
|
|
1. Magazine policy tuning (dedicated file で容易)
|
||
|
|
2. SLL fast path 最適化 (isolation で実験容易)
|
||
|
|
3. Publisher fallback 削減 (cache hit rate 改善)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ドキュメント参照
|
||
|
|
|
||
|
|
- **Full Analysis:** `/mnt/workdisk/public_share/hakmem/STRUCTURAL_ANALYSIS.md`
|
||
|
|
- **Related:** `CLAUDE.md` (Phase 6-2.1 P0 optimization)
|
||
|
|
- **History:** `HISTORY.md` (Past refactoring lessons)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 実施推奨度
|
||
|
|
|
||
|
|
**★★★★★ STRONGLY RECOMMENDED**
|
||
|
|
|
||
|
|
理由:
|
||
|
|
1. hak_tiny_free_with_slab の CC 28 は危険域
|
||
|
|
2. Magazine/SLL paths は独立policy (隔離が自然)
|
||
|
|
3. P0 optimization が superslab_refill に focused
|
||
|
|
4. テスト時の mock 可能性が大幅向上
|
||
|
|
5. Future maintenance が容易に
|
||
|
|
|