Files
hakmem/CURRENT_TASK.md
Moe Charm (CI) bb70d422dc Phase 13-B: TinyHeapV2 supply path with dual-mode A/B framework (Stealing vs Leftover)
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>
2025-11-15 16:28:40 +09:00

201 lines
9.1 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.

# CURRENT TASK Phase 13 (TinyHeapV2 / Tiny + Mid 状況メモ)
**Date**: 2025-11-15
**Status**: 🟡 TinyHeapV2 = 安全な stub / 供給未実装, Mid = 完了, SPSLOT = 完了
**Owner**: ChatGPT → 次フェーズ実装担当: Claude Code
---
## 1. 全体の今どこ
- Tiny (01023B):
- 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 (1KB32KB):
- GAP 修正済み: `MID_MIN_SIZE=1024` に下げて 1KB8KB を Mid が担当。
- Pool TLS ON デフォルトmid ベンチ)で ~10.6M ops/sSystem malloc より速い)。
- Shared SuperSlab Pool (SPSLOT Box):
- 実装完了。SuperSlab 数 -92%、mmap/munmap -48%、Throughput +131%。
- Lock contention (Stage 2) は P0-5 まで実装済み、+23% 程度の改善。
結論: Mid / Shared Pool 側は「研究目的としては一旦完了」。
残りの大きな余白は **Tiny frontC0C3****一部 Tiny ベンチ (Larson / 1KB fixed)**
---
## 2. TinyHeapV2 Box の現状
### 2.1 実装済み (Phase 13-A Alloc Front)
- Box: `TinyHeapV2`per-thread magazine front, C0C3 用の 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` → bit03 で C0C3 有効化。
- `HAKMEM_TINY_HEAP_V2_STATS` → 統計出力 ON。
- `HAKMEM_TINY_HEAP_V2_DEBUG` → 初期デバッグログ。
- 振る舞い:
- `hak_tiny_alloc(size)` が C0C3 かつ mask OK のとき `tiny_heap_v2_alloc(size)` を先に試す。
- `tiny_heap_v2_alloc`:
- mag.top>0 なら popBASE を返す)→ `HAK_RET_ALLOC` で header + user に変換。
- mag 空なら **即 NULL** を返し、既存 front へフォールバック。
- `tiny_heap_v2_refill_mag` は NO-OPrefill なし)。
- `tiny_heap_v2_try_push` は実装済みだが、まだ実際の free/alloc 経路から呼ばれていない想定で OKPhase 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` で 1KB8KB が誰の担当でもなく mmap 直行。
- 今:
- Tiny: `TINY_MAX_SIZE = 1023`(ヘッダ 1B 前提で 1023B まで Tiny
- Mid: `MID_MIN_SIZE = 1024`1KB32KB を 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% 程度の改善。
- SPSLOT 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: 0supply 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 allocatorPool 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 の挙動を見てからで大丈夫。