Files
hakmem/CURRENT_TASK.md

157 lines
7.8 KiB
Markdown
Raw Normal View History

# CURRENT TASK Phase 13 (TinyHeapV2 / Tiny + Mid 状況メモ)
**Date**: 2025-11-15
**Status**: 🟡 TinyHeapV2 = 安全な stub / 供給未実装, Mid = 完了, SPSLOT = 完了
**Owner**: ChatGPT → 次フェーズ実装担当: Claude Code
Fix: CRITICAL multi-threaded freelist/remote queue race condition Root Cause: =========== Freelist and remote queue contained the SAME blocks, causing use-after-free: 1. Thread A (owner): pops block X from freelist → allocates to user 2. User writes data ("ab") to block X 3. Thread B (remote): free(block X) → adds to remote queue 4. Thread A (later): drains remote queue → *(void**)block_X = chain_head → OVERWRITES USER DATA! 💥 The freelist pop path did NOT drain the remote queue first, so blocks could be simultaneously in both freelist and remote queue. Fix: ==== Add remote queue drain BEFORE freelist pop in refill path: core/hakmem_tiny_refill_p0.inc.h: - Call _ss_remote_drain_to_freelist_unsafe() BEFORE trc_pop_from_freelist() - Add #include "superslab/superslab_inline.h" - This ensures freelist and remote queue are mutually exclusive Test Results: ============= BEFORE: larson_hakmem (4 threads): ❌ SEGV in seconds (freelist corruption) AFTER: larson_hakmem (4 threads): ✅ 931,629 ops/s (1073 sec stable run) bench_random_mixed: ✅ 1,020,163 ops/s (no crashes) Evidence: - Fail-Fast logs showed next pointer corruption: 0x...6261 (ASCII "ab") - Single-threaded benchmarks worked (865K ops/s) - Multi-threaded Larson crashed immediately - Fix eliminates all crashes in both benchmarks Files: - core/hakmem_tiny_refill_p0.inc.h: Add remote drain before freelist pop - CURRENT_TASK.md: Document fix details 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 01:35:45 +09:00
---
## 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 まで対処済み(追加改善は高コスト領域として一旦後回し)。
---
## 4. Phase 13-B TinyHeapV2: 次にやること
目的: TinyHeapV2 に **安全な供給経路** を付けて、C0C3 を 25x くらい速くできるか検証する。
Tiny front の研究用 Box。失敗しても ENV で即 OFF に戻せるようにする。)
### 4.1 Box 境界のルール
- TinyHeapV2 は **front-only Box** として扱う:
- Superslab / shared pool / drain には触らない。
- 既存の SLL / FastCache / small_mag の invariants は壊さない。
- supply は「おこぼれ」スタイル:
- 既存 front / free が確定的に成功したあと、その結果の一部を TinyHeapV2 にコピーするだけ。
- primary owner は従来の front/back。TinyHeapV2 が壊れても allocator 全体は壊れないようにする。
### 4.2 具体的 TODOClaude Code 君向け)
1. **現行 free/alloc 経路の確認(ドキュメント化のみ)**
- `core/box/hak_free_api.inc.h` の Tiny 分岐:
- `classify_ptr``PTR_KIND_TINY_HEADER``hak_tiny_free_fast_v2` / `hak_tiny_free`
- `core/hakmem_tiny_alloc_new.inc` の C0C3 経路:
- bump / small_mag / slow path のヒット点をざっくりメモ。
- ここではコード変更より「どの箱を通っているかの図」を更新するのが目的。
2. **Step 13-B-1: alloc 側からの supply低リスク**
- 対象: C0C28/16/32Bだけに限定して開始。
- 場所候補: `hakmem_tiny_alloc_new.inc` の各「成功パス」の直前:
- 例: small_mag ヒットして BASE が決まった直後、`HAK_RET_ALLOC` の直前で:
- `tiny_heap_v2_try_push(class_idx, base);` を 1 回だけ呼ぶENV / class mask でガード)。
- ルール:
- 1 alloc で push してよいのは高々 1 ブロック。
- TinyHeapV2 の mag が満杯なら何もしない(元のパスに影響を与えない)。
- 検証:
- 16/32B fixed-size を対象に:
- `HAKMEM_TINY_HEAP_V2=1`, `..._CLASS_MASK` を C1/C2 のみにして A/B。
- `mag_hits` が >0 になること。
- ベースラインから退化しないこと±5% 以内)。
3. **Step 13-B-2: free 側からの supply中リスク、後半**
- 条件: Step 13-B-1 で「挙動 OK / 性能悪化なし」が確認できてから着手。
- 方針:
- `hak_free_at` の Tiny 分岐、same-thread fast path の **最後** に TinyHeapV2 への push を検討。
- すでに SLL / FastCache に戻したあとで「余剰分」を TinyHeapV2 にコピーする形にする。
- ここはまだ設計だけで OK実装は後続フェーズでも良い
4. **Step 13-C: 評価・チューニング**
- ENV 組み合わせ:
- `HAKMEM_TINY_HEAP_V2=1`
- `HAKMEM_TINY_HEAP_V2_CLASS_MASK` で C0〜C3 を個別に ON/OFF。
- 指標:
- `mag_hits / alloc_calls`hit 率):
- 目標: C1/C2 で 3060% 程度 hit すれば成功。
- 性能:
- fixed-size 16/32B: 既存 ~10M ops/s → 1520M を狙う(+50100%)。
- コード側は Box 境界を守りつつ、mag size, 対象 class, supply トリガ条件などを調整。
---
## 5. 「今は触らない」領域メモ
- Mid-Large allocatorPool TLS + lock-free Stage 1/2:
- SEGV 修正済み、futex 95% 削減、8T で +896% 改善。
- 現時点では研究テーマとしては十分進んだので、Tiny に集中して OK。
- Larson ベンチの 100x 差:
- Lock contention / metadata 再利用の問題が絡む大きめのテーマ。
- TinyHeapV2 がある程度形になってから、別 Phase で攻める。
Front-Direct implementation: SS→FC direct refill + SLL complete bypass ## Summary Implemented Front-Direct architecture with complete SLL bypass: - Direct SuperSlab → FastCache refill (1-hop, bypasses SLL) - SLL-free allocation/free paths when Front-Direct enabled - Legacy path sealing (SLL inline opt-in, SFC cascade ENV-only) ## New Modules - core/refill/ss_refill_fc.h (236 lines): Standard SS→FC refill entry point - Remote drain → Freelist → Carve priority - Header restoration for C1-C6 (NOT C0/C7) - ENV: HAKMEM_TINY_P0_DRAIN_THRESH, HAKMEM_TINY_P0_NO_DRAIN - core/front/fast_cache.h: FastCache (L1) type definition - core/front/quick_slot.h: QuickSlot (L0) type definition ## Allocation Path (core/tiny_alloc_fast.inc.h) - Added s_front_direct_alloc TLS flag (lazy ENV check) - SLL pop guarded by: g_tls_sll_enable && !s_front_direct_alloc - Refill dispatch: - Front-Direct: ss_refill_fc_fill() → fastcache_pop() (1-hop) - Legacy: sll_refill_batch_from_ss() → SLL → FC (2-hop, A/B only) - SLL inline pop sealed (requires HAKMEM_TINY_INLINE_SLL=1 opt-in) ## Free Path (core/hakmem_tiny_free.inc, core/hakmem_tiny_fastcache.inc.h) - FC priority: Try fastcache_push() first (same-thread free) - tiny_fast_push() bypass: Returns 0 when s_front_direct_free || !g_tls_sll_enable - Fallback: Magazine/slow path (safe, bypasses SLL) ## Legacy Sealing - SFC cascade: Default OFF (ENV-only via HAKMEM_TINY_SFC_CASCADE=1) - Deleted: core/hakmem_tiny_free.inc.bak, core/pool_refill_legacy.c.bak - Documentation: ss_refill_fc_fill() promoted as CANONICAL refill entry ## ENV Controls - HAKMEM_TINY_FRONT_DIRECT=1: Enable Front-Direct (SS→FC direct) - HAKMEM_TINY_P0_DIRECT_FC_ALL=1: Same as above (alt name) - HAKMEM_TINY_REFILL_BATCH=1: Enable batch refill (also enables Front-Direct) - HAKMEM_TINY_SFC_CASCADE=1: Enable SFC cascade (default OFF) - HAKMEM_TINY_INLINE_SLL=1: Enable inline SLL pop (default OFF, requires AGGRESSIVE_INLINE) ## Benchmarks (Front-Direct Enabled) ```bash ENV: HAKMEM_BENCH_FAST_FRONT=1 HAKMEM_TINY_FRONT_DIRECT=1 HAKMEM_TINY_REFILL_BATCH=1 HAKMEM_TINY_P0_DIRECT_FC_ALL=1 HAKMEM_TINY_REFILL_COUNT_HOT=256 HAKMEM_TINY_REFILL_COUNT_MID=96 HAKMEM_TINY_BUMP_CHUNK=256 bench_random_mixed (16-1040B random, 200K iter): 256 slots: 1.44M ops/s (STABLE, 0 SEGV) 128 slots: 1.44M ops/s (STABLE, 0 SEGV) bench_fixed_size (fixed size, 200K iter): 256B: 4.06M ops/s (has debug logs, expected >10M without logs) 128B: Similar (debug logs affect) ``` ## Verification - TRACE_RING test (10K iter): **0 SLL events** detected ✅ - Complete SLL bypass confirmed when Front-Direct=1 - Stable execution: 200K iterations × multiple sizes, 0 SEGV ## Next Steps - Disable debug logs in hak_alloc_api.inc.h (call_num 14250-14280 range) - Re-benchmark with clean Release build (target: 10-15M ops/s) - 128/256B shortcut path optimization (FC hit rate improvement) Co-Authored-By: ChatGPT <chatgpt@openai.com> Suggested-By: ultrathink
2025-11-14 05:41:49 +09:00
---
Front-Direct implementation: SS→FC direct refill + SLL complete bypass ## Summary Implemented Front-Direct architecture with complete SLL bypass: - Direct SuperSlab → FastCache refill (1-hop, bypasses SLL) - SLL-free allocation/free paths when Front-Direct enabled - Legacy path sealing (SLL inline opt-in, SFC cascade ENV-only) ## New Modules - core/refill/ss_refill_fc.h (236 lines): Standard SS→FC refill entry point - Remote drain → Freelist → Carve priority - Header restoration for C1-C6 (NOT C0/C7) - ENV: HAKMEM_TINY_P0_DRAIN_THRESH, HAKMEM_TINY_P0_NO_DRAIN - core/front/fast_cache.h: FastCache (L1) type definition - core/front/quick_slot.h: QuickSlot (L0) type definition ## Allocation Path (core/tiny_alloc_fast.inc.h) - Added s_front_direct_alloc TLS flag (lazy ENV check) - SLL pop guarded by: g_tls_sll_enable && !s_front_direct_alloc - Refill dispatch: - Front-Direct: ss_refill_fc_fill() → fastcache_pop() (1-hop) - Legacy: sll_refill_batch_from_ss() → SLL → FC (2-hop, A/B only) - SLL inline pop sealed (requires HAKMEM_TINY_INLINE_SLL=1 opt-in) ## Free Path (core/hakmem_tiny_free.inc, core/hakmem_tiny_fastcache.inc.h) - FC priority: Try fastcache_push() first (same-thread free) - tiny_fast_push() bypass: Returns 0 when s_front_direct_free || !g_tls_sll_enable - Fallback: Magazine/slow path (safe, bypasses SLL) ## Legacy Sealing - SFC cascade: Default OFF (ENV-only via HAKMEM_TINY_SFC_CASCADE=1) - Deleted: core/hakmem_tiny_free.inc.bak, core/pool_refill_legacy.c.bak - Documentation: ss_refill_fc_fill() promoted as CANONICAL refill entry ## ENV Controls - HAKMEM_TINY_FRONT_DIRECT=1: Enable Front-Direct (SS→FC direct) - HAKMEM_TINY_P0_DIRECT_FC_ALL=1: Same as above (alt name) - HAKMEM_TINY_REFILL_BATCH=1: Enable batch refill (also enables Front-Direct) - HAKMEM_TINY_SFC_CASCADE=1: Enable SFC cascade (default OFF) - HAKMEM_TINY_INLINE_SLL=1: Enable inline SLL pop (default OFF, requires AGGRESSIVE_INLINE) ## Benchmarks (Front-Direct Enabled) ```bash ENV: HAKMEM_BENCH_FAST_FRONT=1 HAKMEM_TINY_FRONT_DIRECT=1 HAKMEM_TINY_REFILL_BATCH=1 HAKMEM_TINY_P0_DIRECT_FC_ALL=1 HAKMEM_TINY_REFILL_COUNT_HOT=256 HAKMEM_TINY_REFILL_COUNT_MID=96 HAKMEM_TINY_BUMP_CHUNK=256 bench_random_mixed (16-1040B random, 200K iter): 256 slots: 1.44M ops/s (STABLE, 0 SEGV) 128 slots: 1.44M ops/s (STABLE, 0 SEGV) bench_fixed_size (fixed size, 200K iter): 256B: 4.06M ops/s (has debug logs, expected >10M without logs) 128B: Similar (debug logs affect) ``` ## Verification - TRACE_RING test (10K iter): **0 SLL events** detected ✅ - Complete SLL bypass confirmed when Front-Direct=1 - Stable execution: 200K iterations × multiple sizes, 0 SEGV ## Next Steps - Disable debug logs in hak_alloc_api.inc.h (call_num 14250-14280 range) - Re-benchmark with clean Release build (target: 10-15M ops/s) - 128/256B shortcut path optimization (FC hit rate improvement) Co-Authored-By: ChatGPT <chatgpt@openai.com> Suggested-By: ultrathink
2025-11-14 05:41:49 +09:00
## 6. まとめClaude Code 用の一言メモ)
Front-Direct implementation: SS→FC direct refill + SLL complete bypass ## Summary Implemented Front-Direct architecture with complete SLL bypass: - Direct SuperSlab → FastCache refill (1-hop, bypasses SLL) - SLL-free allocation/free paths when Front-Direct enabled - Legacy path sealing (SLL inline opt-in, SFC cascade ENV-only) ## New Modules - core/refill/ss_refill_fc.h (236 lines): Standard SS→FC refill entry point - Remote drain → Freelist → Carve priority - Header restoration for C1-C6 (NOT C0/C7) - ENV: HAKMEM_TINY_P0_DRAIN_THRESH, HAKMEM_TINY_P0_NO_DRAIN - core/front/fast_cache.h: FastCache (L1) type definition - core/front/quick_slot.h: QuickSlot (L0) type definition ## Allocation Path (core/tiny_alloc_fast.inc.h) - Added s_front_direct_alloc TLS flag (lazy ENV check) - SLL pop guarded by: g_tls_sll_enable && !s_front_direct_alloc - Refill dispatch: - Front-Direct: ss_refill_fc_fill() → fastcache_pop() (1-hop) - Legacy: sll_refill_batch_from_ss() → SLL → FC (2-hop, A/B only) - SLL inline pop sealed (requires HAKMEM_TINY_INLINE_SLL=1 opt-in) ## Free Path (core/hakmem_tiny_free.inc, core/hakmem_tiny_fastcache.inc.h) - FC priority: Try fastcache_push() first (same-thread free) - tiny_fast_push() bypass: Returns 0 when s_front_direct_free || !g_tls_sll_enable - Fallback: Magazine/slow path (safe, bypasses SLL) ## Legacy Sealing - SFC cascade: Default OFF (ENV-only via HAKMEM_TINY_SFC_CASCADE=1) - Deleted: core/hakmem_tiny_free.inc.bak, core/pool_refill_legacy.c.bak - Documentation: ss_refill_fc_fill() promoted as CANONICAL refill entry ## ENV Controls - HAKMEM_TINY_FRONT_DIRECT=1: Enable Front-Direct (SS→FC direct) - HAKMEM_TINY_P0_DIRECT_FC_ALL=1: Same as above (alt name) - HAKMEM_TINY_REFILL_BATCH=1: Enable batch refill (also enables Front-Direct) - HAKMEM_TINY_SFC_CASCADE=1: Enable SFC cascade (default OFF) - HAKMEM_TINY_INLINE_SLL=1: Enable inline SLL pop (default OFF, requires AGGRESSIVE_INLINE) ## Benchmarks (Front-Direct Enabled) ```bash ENV: HAKMEM_BENCH_FAST_FRONT=1 HAKMEM_TINY_FRONT_DIRECT=1 HAKMEM_TINY_REFILL_BATCH=1 HAKMEM_TINY_P0_DIRECT_FC_ALL=1 HAKMEM_TINY_REFILL_COUNT_HOT=256 HAKMEM_TINY_REFILL_COUNT_MID=96 HAKMEM_TINY_BUMP_CHUNK=256 bench_random_mixed (16-1040B random, 200K iter): 256 slots: 1.44M ops/s (STABLE, 0 SEGV) 128 slots: 1.44M ops/s (STABLE, 0 SEGV) bench_fixed_size (fixed size, 200K iter): 256B: 4.06M ops/s (has debug logs, expected >10M without logs) 128B: Similar (debug logs affect) ``` ## Verification - TRACE_RING test (10K iter): **0 SLL events** detected ✅ - Complete SLL bypass confirmed when Front-Direct=1 - Stable execution: 200K iterations × multiple sizes, 0 SEGV ## Next Steps - Disable debug logs in hak_alloc_api.inc.h (call_num 14250-14280 range) - Re-benchmark with clean Release build (target: 10-15M ops/s) - 128/256B shortcut path optimization (FC hit rate improvement) Co-Authored-By: ChatGPT <chatgpt@openai.com> Suggested-By: ultrathink
2025-11-14 05:41:49 +09:00
- **箱の境界**: TinyHeapV2 は「front-only L0 Cache Box」。Superslab / Pool / Drain には触らない。
- **今すぐやること**: alloc 側からの「おこぼれ supply」を 1 箇所だけ差し込んで、統計と A/B を取る。
- **free 側の統合**: 設計だけ整理しておき、実装は TinyHeapV2 の挙動を見てからで大丈夫。