# Phase FREE-TINY-FAST-HOTCOLD-OPT-1 設計(mimalloc 追いかけ:free hot を薄くする) ## 背景(なぜ今これ?) - 直近 perf(Mixed)で `hak_super_lookup` は **0.49% self** → SS map 系は ROI が低い。 - 一方で `free`(wrapper + `free_tiny_fast`)が **~30% self** と最大ボトルネック。 - 現状の `free_tiny_fast` は「多機能を 1 関数に内包」しており、ルート分岐・route snapshot・Larson fix・TinyHeap/v6/v7 などの枝が同居している。 結論: **I-cache/分岐/不要な前処理**が、mimalloc との差として残っている可能性が高い。 (PT や deferred など“正しい研究箱”は freeze で OK。今はホットの削りが勝ち筋。) --- ## 目的 `free_tiny_fast()` を「ホット最小 + コールド分離」に分割し、 - Mixed(標準): **free の self% を下げる**(まずは 1–3pp を目標) - C6-heavy: 既存性能を壊さない(±2% 以内) を狙う。 --- ## 方針(Box Theory) - **箱にする**: `free_tiny_fast` の中で “ホット箱/コールド箱” を分ける。 - **境界 1 箇所**: wrapper 側は変更最小(引き続き `free_tiny_fast(ptr)` だけ呼ぶ)。 - **戻せる**: ENV で A/B(default OFF→実測→昇格)。 - **見える化(最小)**: カウンタは **TLS** のみ(global atomic 禁止)、dump は exit 1回。 - **Fail-Fast**: 不正 header/不正 class は即 `return 0`(従来通り通常 free 経路へ)。 --- ## 変更対象(現状) - `core/box/hak_wrappers.inc.h` から `free_tiny_fast(ptr)` が呼ばれている。 - `core/front/malloc_tiny_fast.h` の `free_tiny_fast()` が巨大で、多数のルートを抱えている。 --- ## 提案アーキテクチャ ### L0: HotBox(always_inline) `free_tiny_fast_hot(ptr, header, class_idx, base)` を新設(static inline)。 **責務**: “ほぼ常に必要な処理だけ” を行い、できるだけ早く `return 1` で終わる。 ホットで残す候補: 1. `ptr` の basic guard(NULL / page boundary) 2. 1-byte header magic check + `class_idx` 取得 3. `base` 計算 4. **最頻ルートの早期 return** - 例: `class_idx==7 && tiny_c7_ultra_enabled_env()` → `tiny_c7_ultra_free(ptr)` → return - 例: policy が `LEGACY` のとき **即 legacy free**(コールドへ落とさない) ### L1: ColdBox(noinline,cold) `free_tiny_fast_cold(ptr, class_idx, base, route_kind, ...)` を新設。 **責務**: 以下の “頻度が低い/大きい” 処理だけを担当する。 - TinyHeap/free-front v3 snapshot 依存の経路 - Larson fix の cross-thread 判定 + remote push - v6/v7 等の研究箱ルート - 付随する debug/trace(ビルドフラグ/ENV でのみ) コールド化の意義: - `free` の I-cache 汚染を減らす(mimalloc の “tiny hot + slow fallback” に寄せる) - 分岐予測の安定化(ホット側の switch を細くする) --- ## ENV / 観測(最小) ### ENV(案) - `HAKMEM_FREE_TINY_FAST_HOTCOLD=0/1`(default 0) - 0: 現状の `free_tiny_fast`(比較用) - 1: Hot/Cold 分割版 ### Stats(案、TLS のみ) - `HAKMEM_FREE_TINY_FAST_HOTCOLD_STATS=0/1`(default 0) - `hot_enter` - `hot_c7_ultra` - `hot_ultra_tls_push` - `hot_mid_v35` - `hot_legacy_direct` - `cold_called` - `ret0_not_tiny_magic` など(戻り 0 の理由別) 注意: - **global atomic は禁止**(過去に stats atomic が 9〜10% 外乱になったため)。 - dump は `atexit` or pthread_key destructor で **1 回だけ**。 --- ## 実装順序(小パッチ) 1. **ENV gate 箱**: `*_env_box.h`(default OFF、キャッシュ化) 2. **Stats 箱**: TLS カウンタ + dump(default OFF) 3. **Hot/Cold 分割**: `free_tiny_fast()` 内で - header/class/base を取る - “ホットで完結できるか” 判定 - それ以外だけ `cold()` に委譲 4. **健康診断ラン**: `scripts/verify_health_profiles.sh` を OFF/ON で実行 5. **A/B**: - Mixed: `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE`(中央値 + 分散) - C6-heavy: `HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1` 6. **perf**: `free` self% と `branch-misses` の差を確認(目標: free self% 減) --- ## 判定ゲート(freeze/graduate) - Gate 1(安全): health profile PASS(OFF/ON) - Gate 2(性能): - Mixed: -2% 以内(理想は +0〜+数%) - C6-heavy: ±2% 以内 - Gate 3(観測): stats ON 時に “cold_called が低い/理由が妥当” を確認 満たせなければ **研究箱として freeze(default OFF)**。 freeze は失敗ではなく、Box Theory の成果として保持する。