Files
hakmem/docs/archive/WHAT_IS_DYNAMIC.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

406 lines
8.8 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.

# Phase 7.6: 何を「動的」にするのか?
**日付:** 2025-10-26
**質問:** "となると どこを動的にするんですかにゃ?"
---
## 🎯 結論SuperSlabの「生と死」を動的に
### Phase 7.6で動的にするもの
**1つだけです** SuperSlabのライフサイクル
```
❌ 現状(半分だけ動的):
割当: 動的(初回アクセス時に確保)✅
解放: 固定(一度確保したら永遠に保持)❌
✅ Phase 7.6(完全動的):
割当: 動的(初回アクセス時に確保)✅
解放: 動的空になったらOSに返却✅ ← これを実装!
```
---
## 📊 現状分析:何が固定で何が動的?
### 現在の実装Phase 6.24
**データ構造:**
```c
// TLS cacheスレッドごと
static __thread TinyTLSSlab g_tls_slabs[TINY_NUM_CLASSES];
typedef struct {
SuperSlab* ss; // SuperSlab pointer
TinySlabMeta* meta; // Slab metadata cache
uint8_t slab_idx; // Current slab index
} TinyTLSSlab;
```
**割当フロー:**
```c
malloc(16)
hak_tiny_alloc_superslab(class_idx=1) // 16B = class 1
TinyTLSSlab* tls = &g_tls_slabs[1];
if (tls->ss == NULL || slab満杯) {
superslab_refill(1); // ← 初回アクセス時に確保(動的!)
SuperSlab* ss = superslab_allocate(1); // mmap(2MB)
tls->ss = ss; // TLS cacheに保存
}
return block;
```
**解放フロー:**
```c
free(ptr)
hak_tiny_free(ptr)
Magazine push // ← ここで止まる
SuperSlabへの通知なし
OSへの返却なし)← ずっと保持!
```
---
## 🔍 何が「固定」で何が「動的」?
### 固定のものPhase 7.6でも変更なし)
| 項目 | 値 | 理由 |
|------|-----|------|
| SuperSlabサイズ | 2MB | mimalloc準拠、最適 |
| Slabサイズ | 64KB | 2MB / 32 = 64KB |
| Slabs per SuperSlab | 32個 | 固定bitmap効率 |
| サイズクラス | 8種8-64B | Tiny Pool範囲固定 |
| Magazine CAP | クラスごと固定 | 現状で十分高性能 |
**これらは変更しません!**
### 動的のもの(すでに実装済み)
| 項目 | 現状 | 実装 |
|------|------|------|
| SuperSlab割当 | ✅ 動的 | `superslab_refill()` で初回アクセス時 |
| Slab初期化 | ✅ 動的 | 必要になったslabのみ初期化 |
| TLS cache | ✅ 動的 | スレッドごとに自動管理 |
**これらはすでに動的です!**
### Phase 7.6で追加する動的要素
| 項目 | 現状 | Phase 7.6後 |
|------|------|-------------|
| **SuperSlab解放** | ❌ 固定(永遠保持) | ✅ 動的(空なら返却) |
**これだけです!** シンプルですね 🎯
---
## 🎨 図解:何が動的になるのか
### Before Phase 7.6(現状)
```
時間軸 →
起動時:
g_tls_slabs[0..7] = {NULL, NULL, ...} // 初期化のみ
SuperSlabs: 0個
初回 malloc(16):
superslab_refill(1) → mmap(2MB) → SuperSlab確保 ✅
g_tls_slabs[1].ss = SuperSlab#1
SuperSlabs: 1個
100K malloc(16):
必要に応じてSuperSlab確保 ✅
SuperSlabs: 3個
100K free(ptr):
Magazineにpush → SuperSlabは保持 ❌
SuperSlabs: 3個そのまま
500K malloc(16):
さらにSuperSlab確保 ✅
SuperSlabs: 7個
500K free(ptr):
Magazineにpush → SuperSlabは保持 ❌
SuperSlabs: 7個そのまま
1M malloc(16):
さらにSuperSlab確保 ✅
SuperSlabs: 13個
1M free(ptr):
Magazineにpush → SuperSlabは保持 ❌
SuperSlabs: 13個永遠に保持← 問題!
```
**結果:**
- 割当は動的 ✅(必要な時だけ確保)
- 解放は固定 ❌(一度確保したら永遠保持)
- **メモリが無駄!** 26MB常駐
---
### After Phase 7.6(目標)
```
時間軸 →
起動時:
g_tls_slabs[0..7] = {NULL, NULL, ...}
SuperSlabs: 0個 ✅
初回 malloc(16):
superslab_refill(1) → mmap(2MB) ✅
SuperSlabs: 1個
100K malloc(16):
SuperSlabs: 3個 ✅
100K free(ptr):
Magazine + SuperSlab追跡 ✅
total_active_blocks -= 100K
空SuperSlab検出 → munmap(2MB) × 3 ✅
SuperSlabs: 0個解放← 新機能!
500K malloc(16):
SuperSlabs: 7個 ✅
500K free(ptr):
空SuperSlab検出 → munmap × 7 ✅
SuperSlabs: 0個解放
1M malloc(16):
SuperSlabs: 13個 ✅
1M free(ptr):
空SuperSlab検出 → munmap × 13 ✅
SuperSlabs: 0個解放
終了時:
SuperSlabs: 0個 ✅
メモリ: ~2-3 MBMagazineのみ
```
**結果:**
- 割当は動的 ✅(必要な時だけ確保)
- 解放も動的 ✅(空になったら返却)← NEW!
- **メモリ効率MAX** 使用中のみ保持
---
## 🎯 具体的に「動的」とは?
### SuperSlabのライフサイクル
**Before半分動的**
```
Birth誕生: 動的 ✅
↓ malloc時、必要になったら
superslab_allocate() → mmap(2MB)
Life生存: 使用中
↓ malloc/freeを繰り返す
blocks割当・解放
Death: なし ❌
↓ プロセス終了まで
(永遠に保持)
```
**After Phase 7.6(完全動的):**
```
Birth誕生: 動的 ✅
↓ malloc時、必要になったら
superslab_allocate() → mmap(2MB)
Life生存: 使用中
↓ malloc/freeを繰り返す
total_active_blocks の増減を追跡 ← NEW!
Death: 動的 ✅ ← NEW!
↓ total_active_blocks == 0 になったら
superslab_free() → munmap(2MB) ← NEW!
OSへ返却、メモリ解放
```
---
## 📋 Phase 7.6の実装:具体的に何をする?
### Step 1-2: Magazine統合freeの追跡
**目的:** SuperSlabが「いつ空になったか」を検出
**実装:**
```c
// hakmem_tiny.c:908-912Magazine push
if (mag->top < cap) {
mag->items[mag->top].ptr = ptr;
mag->top++;
// Phase 7.6: 追跡追加 ← NEW!
SuperSlab* ss = ptr_to_superslab(ptr);
if (ss && ss->magic == SUPERSLAB_MAGIC) {
ss->total_active_blocks--; // カウンタ減算
}
return;
}
```
**これで:**
- ✅ freeを追跡できる
-`total_active_blocks` が正確になる
- ✅ 空検出が可能に
### Step 3: 空SuperSlab解放Deathの実装
**目的:** 空になったらOSに返却
**実装:**
```c
if (ss->total_active_blocks == 0) {
// 完全に空!
superslab_free(ss); // munmap(2MB) ← NEW!
g_tls_slabs[class_idx].ss = NULL; // TLS cacheクリア
}
```
**これで:**
- ✅ 空SuperSlabを解放
- ✅ OSにメモリ返却
- ✅ メモリ効率MAX
### Step 4: 遅延割当(すでに実装済み)
**現状:**
```c
// superslab_refill() (line 1027)
// 初回アクセス時のみ確保 ← すでに動的!
if (tls->ss == NULL) {
tls->ss = superslab_allocate(class_idx);
}
```
**Phase 7.6で追加:**
- 特になし!
- すでに遅延割当されている
**でも明示的に:**
```c
// グローバル配列も管理(解放追跡用)
static SuperSlab* g_active_superslabs[TINY_NUM_CLASSES] = {NULL};
```
---
## 🎓 他の「動的」との違い
### ACEの「動的」Mid/Large Pool
**何が動的?**
- CAP在庫量: ヒット率で調整
- W_MAX丸め度: UCB1学習
- しきい値: Canaryテスト
**手法:** 学習ベース
### Phase 7.6の「動的」Tiny Pool
**何が動的?**
- SuperSlabの解放: 空検出で返却
**手法:** 設計ベースBitmapの柔軟性
**共通点:**
- どちらも「必要な時だけ確保、不要になったら解放」
- でも実装手法が異なる
---
## 🚀 まとめ
### Phase 7.6で動的にするもの
**たった1つ**
```
SuperSlabの解放
```
**具体的には:**
```c
// Before
SuperSlab確保 永遠保持
// After
SuperSlab確保 使用 空検出 OS返却
```
**これだけです!**
### なぜ「全部動的」と言ったのか?
**「全部動的」の意味:**
```
割当も動的 ✅(すでに実装済み)
解放も動的 ✅Phase 7.6で追加)
= SuperSlabのライフサイクル全体が動的
= 「全部動的」
```
**vs 中途半端(悪い例):**
```
割当は動的 ✅
解放は固定 ❌
= 半分だけ動的
= 中途半端 ❌
```
### 他に動的にしないもの
**これらは固定のまま:**
- ❌ SuperSlabサイズ2MB固定
- ❌ サイズクラス8種固定
- ❌ Magazine CAPクラスごと固定
**理由:**
- すでに最適
- 動的化の価値なし
- ACEと同じ「動的1個問題」を避ける
---
## 🎯 次のステップ
**やること:**
1. Magazine統合Step 1-2
2. 空SuperSlab解放Step 3
**やらないこと:**
- SuperSlabサイズの動的化不要
- Magazine CAPの学習不要
- ACE統合独立が美しい
**にゃーん!わかりましたか?** 🐱
---
**次:** Step 1実装を始めましょう