Summary: - Implemented free path supply with ENV-gated A/B modes (HAKMEM_TINY_HEAP_V2_LEFTOVER_MODE) - Mode 0 (Stealing, default): L0 gets freed blocks first → +18% @ 32B - Mode 1 (Leftover): L1 primary owner, L0 gets leftovers → Box-clean but -5% @ 16B - Decision: Default to Stealing for performance (ChatGPT analysis: L0 doesn't corrupt learning layer signals) Performance (100K iterations, workset=128): - 16B: 43.9M → 45.6M ops/s (+3.9%) - 32B: 41.9M → 49.6M ops/s (+18.4%) ✅ - 64B: 51.2M → 51.5M ops/s (+0.6%) - 100% magazine hit rate (supply from free path working correctly) Implementation: - tiny_free_fast_v2.inc.h: Dual-mode supply (lines 134-166) - tiny_heap_v2.h: Add tiny_heap_v2_leftover_mode() flag + rationale doc - tiny_alloc_fast.inc.h: Alloc hook with tiny_heap_v2_alloc_by_class() - CURRENT_TASK.md: Updated Phase 13-B status (complete) with A/B results ENV flags: - HAKMEM_TINY_HEAP_V2=1 # Enable TinyHeapV2 - HAKMEM_TINY_HEAP_V2_LEFTOVER_MODE=0 # Mode 0 (Stealing, default) - HAKMEM_TINY_HEAP_V2_CLASS_MASK=0xE # C1-C3 only (skip C0 -5% regression) - HAKMEM_TINY_HEAP_V2_STATS=1 # Print statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
201 lines
9.1 KiB
Markdown
201 lines
9.1 KiB
Markdown
# CURRENT TASK – Phase 13 (TinyHeapV2 / Tiny + Mid 状況メモ)
|
||
|
||
**Date**: 2025-11-15
|
||
**Status**: 🟡 TinyHeapV2 = 安全な stub / 供給未実装, Mid = 完了, SP‑SLOT = 完了
|
||
**Owner**: ChatGPT → 次フェーズ実装担当: Claude Code
|
||
|
||
---
|
||
|
||
## 1. 全体の今どこ
|
||
|
||
- Tiny (0–1023B):
|
||
- Front: NEW 3-layer front (bump / small_mag / slow) 安定。
|
||
- TinyHeapV2: 「alloc フロント+統計」実装済みだが、magazine 供給なし → hit 率 0%。
|
||
- Drain: TLS SLL drain interval = 2048(デフォルト)。Tiny random mixed で ~9M ops/s レベル。
|
||
- Mid (1KB–32KB):
|
||
- GAP 修正済み: `MID_MIN_SIZE=1024` に下げて 1KB–8KB を Mid が担当。
|
||
- Pool TLS ON デフォルト(mid ベンチ)で ~10.6M ops/s(System malloc より速い)。
|
||
- Shared SuperSlab Pool (SP‑SLOT Box):
|
||
- 実装完了。SuperSlab 数 -92%、mmap/munmap -48%、Throughput +131%。
|
||
- Lock contention (Stage 2) は P0-5 まで実装済み、+2–3% 程度の改善。
|
||
|
||
結論: Mid / Shared Pool 側は「研究目的としては一旦完了」。
|
||
残りの大きな余白は **Tiny front(C0–C3)** と **一部 Tiny ベンチ (Larson / 1KB fixed)**。
|
||
|
||
---
|
||
|
||
## 2. TinyHeapV2 Box の現状
|
||
|
||
### 2.1 実装済み (Phase 13-A – Alloc Front)
|
||
|
||
- Box: `TinyHeapV2`(per-thread magazine front, C0–C3 用の L0 キャッシュ)
|
||
- ファイル:
|
||
- `core/front/tiny_heap_v2.h`
|
||
- `core/hakmem_tiny.c`(TLS 定義 + 統計出力)
|
||
- `core/hakmem_tiny_alloc_new.inc`(alloc hook)
|
||
- TLS 構造:
|
||
- `__thread TinyHeapV2Mag g_tiny_heap_v2_mag[TINY_NUM_CLASSES];`
|
||
- `__thread TinyHeapV2Stats g_tiny_heap_v2_stats[TINY_NUM_CLASSES];`
|
||
- ENV:
|
||
- `HAKMEM_TINY_HEAP_V2` → Box ON/OFF。
|
||
- `HAKMEM_TINY_HEAP_V2_CLASS_MASK` → bit0–3 で C0–C3 有効化。
|
||
- `HAKMEM_TINY_HEAP_V2_STATS` → 統計出力 ON。
|
||
- `HAKMEM_TINY_HEAP_V2_DEBUG` → 初期デバッグログ。
|
||
- 振る舞い:
|
||
- `hak_tiny_alloc(size)` が C0–C3 かつ mask OK のとき `tiny_heap_v2_alloc(size)` を先に試す。
|
||
- `tiny_heap_v2_alloc`:
|
||
- mag.top>0 なら pop(BASE を返す)→ `HAK_RET_ALLOC` で header + user に変換。
|
||
- mag 空なら **即 NULL** を返し、既存 front へフォールバック。
|
||
- `tiny_heap_v2_refill_mag` は NO-OP(refill なし)。
|
||
- `tiny_heap_v2_try_push` は実装済みだが、まだ実際の free/alloc 経路から呼ばれていない想定で OK(Phase 13-B で使う)。
|
||
- 現状の性能:
|
||
- 16/32/64B fixed-size (100K) で ±1% 以内 → hook オーバーヘッドはほぼゼロ。
|
||
- `alloc_calls` は 200K まで増えるが `mag_hits=0`(supply なしのため)。
|
||
|
||
**要点:** TinyHeapV2 は「壊さず差し込めた L0 stub」。
|
||
これから **supply をどう設計するか** が Phase 13-B の主題。
|
||
|
||
---
|
||
|
||
## 3. 最近のバグ修正・仕様調整(もう触らなくてよい箱)
|
||
|
||
### 3.1 Tiny / Mid サイズ境界ギャップ修正(完了)
|
||
|
||
- 以前:
|
||
- `TINY_MAX_SIZE = 1024` / `MID_MIN_SIZE = 8192` で 1KB–8KB が誰の担当でもなく mmap 直行。
|
||
- 今:
|
||
- Tiny: `TINY_MAX_SIZE = 1023`(ヘッダ 1B 前提で 1023B まで Tiny)。
|
||
- Mid: `MID_MIN_SIZE = 1024`(1KB–32KB を Mid MT が処理)。
|
||
- 効果:
|
||
- `bench_fixed_size_hakmem 1024B` が mmap 地獄から脱出 → Mid MT 経路で ~0.5M ops/s レベルに改善。
|
||
- SEGV は解消。今残っているのは性能ギャップだけ(TinyHeapV2 とは独立)。
|
||
|
||
### 3.2 Shared Pool / LRU / Drain 周り
|
||
|
||
- TLS SLL drain:
|
||
- `HAKMEM_TINY_SLL_DRAIN_INTERVAL` デフォルト = 2048。
|
||
- 128/256B 固定サイズで A/B 済み。どちらも退化なく、むしろ +5〜+15% 程度の改善。
|
||
- SP‑SLOT Box:
|
||
- SuperSlab 数削減・syscall 削減は期待通り。
|
||
- futex / lock contention は P0-5 まで対処済み(追加改善は高コスト領域として一旦後回し)。
|
||
|
||
### 3.3 ✅ CRITICAL FIX: workset=128 Infinite Recursion Bug (2025-11-15)
|
||
|
||
**Commit**: 176bbf656
|
||
|
||
**Root Cause**:
|
||
- `shared_pool_ensure_capacity_unlocked()` used `realloc()` for Shared Pool metadata allocation
|
||
- `realloc()` → `hak_alloc_at(128B)` → `shared_pool_init()` → `realloc()` → **INFINITE RECURSION**
|
||
- Triggered by high memory pressure (workset=128) but not lower pressure (workset=64)
|
||
|
||
**Symptoms**:
|
||
- `bench_fixed_size_hakmem 1 16 128`: infinite hang (timeout)
|
||
- `bench_fixed_size_hakmem 1 1024 128`: worked fine (4.3M ops/s)
|
||
- **Size-class specific**: C1-C3 (16-64B) hung, C7 (1024B) worked
|
||
- Reason: Small allocations trigger more SuperSlab allocations → more metadata realloc → deeper recursion
|
||
|
||
**Fix** (`core/hakmem_shared_pool.c`):
|
||
- Replace `realloc()` with direct system `mmap()` for Shared Pool metadata
|
||
- Use `munmap()` to free old mappings (not `free()`!)
|
||
- **Breaks recursion**: Shared Pool metadata now allocated outside HAKMEM allocator
|
||
|
||
**Performance** (before → after):
|
||
- 16B / workset=128: **timeout → 18.5M ops/s** ✅ FIXED
|
||
- 1024B / workset=128: 4.3M ops/s → stable (no regression)
|
||
- 16B / workset=64: 44M ops/s → stable (no regression)
|
||
|
||
**Testing**:
|
||
```bash
|
||
# Critical test (previously hung indefinitely)
|
||
./out/release/bench_fixed_size_hakmem 10000 256 128
|
||
# Expected: ~18M ops/s, instant completion
|
||
```
|
||
|
||
**Key Lesson**:
|
||
- Never use allocator-managed memory for the allocator's own metadata
|
||
- Bootstrap phase must use system primitives (mmap) directly
|
||
- Workset size can expose hidden recursion bugs under memory pressure
|
||
|
||
---
|
||
|
||
## 4. Phase 13-B – TinyHeapV2: Supply 経路実装 ✅ 完了
|
||
|
||
**Status**: 2025-11-15 完了
|
||
**結果**: **Stealing 設計を採用(Mode 0 デフォルト)、32B で +18% 改善**
|
||
|
||
### 4.1 実装完了内容
|
||
|
||
1. ✅ **Free path supply 実装** (`core/tiny_free_fast_v2.inc.h`)
|
||
- 2 つの supply モードを実装(ENV で A/B 可能):
|
||
- **Mode 0 (Stealing)**: L0 が free を先に受け取る(デフォルト)
|
||
- **Mode 1 (Leftover)**: L1 primary owner, L0 は「おこぼれ」
|
||
|
||
2. ✅ **Alloc path hook 実装** (`core/tiny_alloc_fast.inc.h`)
|
||
- `tiny_heap_v2_alloc_by_class(class_idx)` - 最適化済み(-47% 退化を +14% 改善に修正)
|
||
- class_idx を直接受け取り、冗長な変換・チェックを削除
|
||
|
||
3. ✅ **ENV フラグ完備**:
|
||
- `HAKMEM_TINY_HEAP_V2` - Box ON/OFF
|
||
- `HAKMEM_TINY_HEAP_V2_CLASS_MASK` - class 別有効化(bitmask)
|
||
- `HAKMEM_TINY_HEAP_V2_LEFTOVER_MODE` - Mode 0/1 切り替え
|
||
- `HAKMEM_TINY_HEAP_V2_STATS` - 統計出力
|
||
|
||
### 4.2 A/B テスト結果(100K iterations, workset=128)
|
||
|
||
| サイズ | Baseline (V2 OFF) | **Mode 0 (Stealing)** | Mode 1 (Leftover) |
|
||
|--------|------------------|----------------------|------------------|
|
||
| **16B** | 43.9M ops/s | **45.6M (+3.9%)** ✅ | 41.6M (-5.2%) ❌ |
|
||
| **32B** | 41.9M ops/s | **49.6M (+18.4%)** ✅ | 41.1M (-1.9%) ❌ |
|
||
| **64B** | 51.2M ops/s | **51.5M (+0.6%)** ≈ | 51.0M (-0.4%) ≈ |
|
||
|
||
**統計**(Mode 0 @ 16B):
|
||
- alloc_calls: 99,872
|
||
- mag_hits: 99,872 (**100.0% hit rate**)
|
||
- refill: 0(supply from free path のみ)
|
||
|
||
### 4.3 設計判断:Stealing をデフォルトに採用
|
||
|
||
**ChatGPT 先生の分析**(ultrathink 相談):
|
||
|
||
1. **学習層との整合性 OK**:
|
||
- 学習層は主に Superslab / Pool / Drain の統計を見る
|
||
- L0 stealing は Superslab 側の carving/drain 信号を壊さない
|
||
- 必要なら TinyHeapV2 の hit/miss カウンタを学習用フックとして追加すれば良い
|
||
|
||
2. **Box 境界の整理**:
|
||
- TinyHeapV2 は **front-only Box** として完結
|
||
- 学習層には「Superslab/Pool の世界」と「L0/L1 の統計」を別々の箱として渡す
|
||
- 性能 (+18%) > 厳格な Box 境界
|
||
|
||
3. **推奨方針**:
|
||
- **今は Stealing で性能を攻める**(Mode 0 デフォルト)
|
||
- 学習層との整合は後続 Phase で必要に応じて調整
|
||
|
||
**決定**: `HAKMEM_TINY_HEAP_V2_LEFTOVER_MODE=0` (Stealing) をデフォルトに採用。
|
||
**根拠**: 32B で +18% の性能改善、学習層への影響は軽微。
|
||
|
||
### 4.4 残タスク(後続 Phase)
|
||
|
||
- [ ] **C0 (8B) の最適化**: 現在 -5% 退化 → CLASS_MASK で無効化を検討
|
||
- [ ] **学習層統合**: 必要に応じて TinyHeapV2 の hit/miss/refill カウンタを学習用フックとして追加
|
||
- [ ] **Random mixed ベンチ**: 256B mixed workload でも A/B テスト
|
||
|
||
---
|
||
|
||
## 5. 「今は触らない」領域メモ
|
||
|
||
- Mid-Large allocator(Pool TLS + lock-free Stage 1/2):
|
||
- SEGV 修正済み、futex 95% 削減、8T で +896% 改善。
|
||
- 現時点では研究テーマとしては十分進んだので、Tiny に集中して OK。
|
||
- Larson ベンチの 100x 差:
|
||
- Lock contention / metadata 再利用の問題が絡む大きめのテーマ。
|
||
- TinyHeapV2 がある程度形になってから、別 Phase で攻める。
|
||
|
||
---
|
||
|
||
## 6. まとめ(Claude Code 用の一言メモ)
|
||
|
||
- **箱の境界**: TinyHeapV2 は「front-only L0 Cache Box」。Superslab / Pool / Drain には触らない。
|
||
- **今すぐやること**: alloc 側からの「おこぼれ supply」を 1 箇所だけ差し込んで、統計と A/B を取る。
|
||
- **free 側の統合**: 設計だけ整理しておき、実装は TinyHeapV2 の挙動を見てからで大丈夫。
|