diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 89644b32..563165ea 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -43,13 +43,22 @@ - 指示書(記録): `docs/analysis/PHASE7_FRONT_FASTLANE_FREE_HOTCOLD_1_NEXT_INSTRUCTIONS.md` - 対処: Rollback 済み(FastLane free は `free_tiny_fast()` 維持) -### Next: Phase 8(次の芯) +### Phase 8 FREE-STATIC-ROUTE-ENV-CACHE-FIX: FREE-STATIC-ROUTE ENV Cache Hardening — ✅ GO / 本線昇格 + +結果: Mixed 10-run mean **+2.61%**、標準偏差 **-61%**。`bench_profile` の `putenv()` が main 前の ENV キャッシュ事故に負けて D1 が効かない問題を修正し、既存の勝ち箱(Phase 3 D1)が確実に効く状態を作った(本線品質向上)。 + +- 指示書(完了): `docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_NEXT_INSTRUCTIONS.md` +- 実装 + A/B: `docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_AB_TEST_RESULTS.md` +- コミット: `be723ca05` + +### Next: Phase 9(次の芯) 優先候補(GO を狙う小パッチ): -1) **Phase 8: FREE-STATIC-ROUTE ENV cache hardening** - - 症状: `HAKMEM_FREE_STATIC_ROUTE=1` を `bench_profile` で設定しても、プロセス初期の malloc/free で gate が先に 0 をキャッシュしてしまい、D1 が効かないことがある(`[FREE_STATIC_ROUTE] enabled` が出ない/`tiny_route_for_class` が perf に残る)。 - - 狙い: 既存の勝ち箱(Phase 3 D1)を “本当に” 有効化し、free の `tiny_route_for_class()` 固定費を削る。 - - 指示書: `docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_NEXT_INSTRUCTIONS.md` +1) **Phase 9: FREE-TINY-FAST MONO DUALHOT (FastLane 対応)** + - 背景: Phase 7(FastLane free を hot/cold に合わせる)は NO-GO。FastLane free は monolithic `free_tiny_fast()` を維持する必要がある。 + - 狙い: wrapper 側で勝っている “C0–C3 は第2ホット” を、**monolithic `free_tiny_fast()` 側に最小固定費で移植**し、FastLane free でも効く状態にする(hot/cold split は持ち込まない)。 + - 期待: +1〜4%(C0–C3 が支配的な Mixed で上振れあり) + - 指示書: `docs/analysis/PHASE9_FREE_TINY_FAST_MONO_DUALHOT_1_NEXT_INSTRUCTIONS.md` ## 更新メモ(2025-12-14 Phase 5 E5-3 Analysis - Strategic Pivot) diff --git a/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_AB_TEST_RESULTS.md b/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_AB_TEST_RESULTS.md index 750dbb30..52c4546f 100644 --- a/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_AB_TEST_RESULTS.md +++ b/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_AB_TEST_RESULTS.md @@ -11,8 +11,8 @@ Phase 3 D1(`HAKMEM_FREE_STATIC_ROUTE=1`)は「`tiny_route_for_class()` の ### Patch 1: ENV gate を "refresh 可能" にする **対象ファイル**: -- 新規: `/mnt/workdisk/public_share/hakmem/core/box/tiny_free_route_cache_env_box.c` -- 修正: `/mnt/workdisk/public_share/hakmem/core/box/tiny_free_route_cache_env_box.h` +- 新規: `core/box/tiny_free_route_cache_env_box.c` +- 修正: `core/box/tiny_free_route_cache_env_box.h` **変更内容**: - header 内 `static int g_free_static_route_enabled` を廃止し、**単一のグローバル状態**に寄せた @@ -30,7 +30,7 @@ Phase 3 D1(`HAKMEM_FREE_STATIC_ROUTE=1`)は「`tiny_route_for_class()` の ### Patch 2: bench_profile の "ENV 反映" に組み込む -**対象ファイル**: `/mnt/workdisk/public_share/hakmem/core/bench_profile.h` +**対象ファイル**: `core/bench_profile.h` **変更内容**: - `bench_apply_profile()` の `bench_setenv_default()` 群の後にある refresh 群に追加: @@ -41,7 +41,7 @@ Phase 3 D1(`HAKMEM_FREE_STATIC_ROUTE=1`)は「`tiny_route_for_class()` の ### Patch 3: Makefile 修正 -**対象ファイル**: `/mnt/workdisk/public_share/hakmem/Makefile` +**対象ファイル**: `Makefile` **変更内容**: - `BENCH_HAKMEM_OBJS_BASE` と `TINY_BENCH_OBJS_BASE` に `core/box/tiny_free_route_cache_env_box.o` を追加 diff --git a/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_NEXT_INSTRUCTIONS.md b/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_NEXT_INSTRUCTIONS.md index 6a9c4231..080909d0 100644 --- a/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_NEXT_INSTRUCTIONS.md +++ b/docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_NEXT_INSTRUCTIONS.md @@ -1,5 +1,12 @@ # Phase 8: FREE-STATIC-ROUTE ENV cache hardening(次の指示書) +## Status(2025-12-14) + +**✅ GO / 本線昇格(+2.61% Mixed 10-run, σ -61%)** + +- A/B 結果: `docs/analysis/PHASE8_FREE_STATIC_ROUTE_ENV_CACHE_FIX_1_AB_TEST_RESULTS.md` +- コミット: `be723ca05` + ## 0. 目的(狙い) Phase 3 D1(`HAKMEM_FREE_STATIC_ROUTE=1`)は「`tiny_route_for_class()` の固定費を消す」勝ち箱だが、**プロセス初期の malloc/free(main 前)で ENV gate が先に 0 をキャッシュ**すると、`bench_profile` が後から `putenv()` で `HAKMEM_FREE_STATIC_ROUTE=1` を設定しても D1 が効かないことがある。 @@ -102,4 +109,3 @@ scripts/verify_health_profiles.sh - `HAKMEM_FREE_STATIC_ROUTE=0` - もしくは Patch 1/2 を revert - diff --git a/docs/analysis/PHASE9_FREE_TINY_FAST_MONO_DUALHOT_1_NEXT_INSTRUCTIONS.md b/docs/analysis/PHASE9_FREE_TINY_FAST_MONO_DUALHOT_1_NEXT_INSTRUCTIONS.md new file mode 100644 index 00000000..d1343620 --- /dev/null +++ b/docs/analysis/PHASE9_FREE_TINY_FAST_MONO_DUALHOT_1_NEXT_INSTRUCTIONS.md @@ -0,0 +1,143 @@ +# Phase 9: FREE-TINY-FAST MONO DUALHOT(FastLane 対応)次の指示書 + +## 0. 目的(狙い) + +Phase 6 FastLane + Phase 6-2 Free DeDup により、Mixed の free は主に **FastLane → monolithic `free_tiny_fast()`** を通る。 + +一方で “第2ホット” の勝ち筋(`FREE-TINY-FAST-DUALHOT-1`: C0–C3 を policy snapshot なしで最短処理)は、主に **`free_tiny_fast_hot()` 側**に実装されており、Phase 7(FastLane から hot/cold に寄せる)は **NO-GO** だった。 + +この Phase 9 は、**hot/cold split を持ち込まず**に、勝ち筋だけ(C0–C3 direct)を **monolithic `free_tiny_fast()` 側へ最小固定費で移植**し、FastLane free でも効く状態にする。 + +## 1. 現状と問題(ねじれの再定義) + +- wrapper 経由の free: + - `HAKMEM_FREE_TINY_FAST_HOTCOLD=1` のとき `free_tiny_fast_hot()` が使われ、C0–C3 DUALHOT が効く +- FastLane free: + - Phase 6-2 DeDup により `front_fastlane_try_free()` は `free_tiny_fast()` へ直行(hot/cold は使わない) + - その結果、C0–C3 の “第2ホット” が **FastLane では効きにくい** + +Phase 7 は “関数 split(hot/cold)” を合わせに行って負けたので、次は **monolithic 内での early-exit** に寄せる。 + +## 2. 設計方針(Box Theory) + +- 箱(L0/L1): + - L0: `FreeTinyFastMonoDualHotEnvBox`(ENV gate のみ、A/B と即 rollback のため) + - L1: `free_tiny_fast()`(monolithic hot path 本体) +- 境界: + - “変換点” は `free_tiny_fast()` 冒頭(header→class/base 確定直後)に 1 箇所だけ作る + - それ以外の経路は既存の `free_tiny_fast()` を一切崩さない +- 戻せる: + - ENV で OFF にできる(同一バイナリ A/B) +- Fail-Fast: + - 断定できない条件(route snapshot 未初期化 / TinyHeap route / Larson fix)では必ず既存経路へ落とす +- 見える化(最小): + - `HAKMEM_DEBUG_COUNTERS=1` のときだけ `FREE_PATH_STAT_INC(mono_dualhot_hit)` を 1 箇所入れる(常時ログは入れない) + +## 3. 仕様(MONO DUALHOT の条件) + +`free_tiny_fast()` 内で、以下の条件を満たす場合のみ direct path を許可する: + +- `HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=1` +- `class_idx <= 3`(C0–C3) +- `!HAKMEM_TINY_LARSON_FIX`(Larson fix ON のときは cross-thread 判定が必要なので direct 禁止) +- `g_tiny_route_snapshot_done == 1` かつ `g_tiny_route_class[class_idx] == TINY_ROUTE_LEGACY` + - TinyHeap / HotHeap / small-heap route に誤って入らないため(断定できないときは既存経路) + +direct path の中身: +- `tiny_legacy_fallback_free_base(base, class_idx);` +- `return 1;` + +## 4. 実装指示(小パッチ順) + +### Patch 1: ENV gate 箱を追加(L0) + +新規: +- `core/box/free_tiny_fast_mono_dualhot_env_box.h` + +API: +- `static inline int free_tiny_fast_mono_dualhot_enabled(void)` + +要件: +- ENV: `HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=0/1`(default 0) +- **probe window 64**(bench_profile の putenv 競合を吸収) +- hot path は「cached==1/0 の即 return」だけ + +### Patch 2: `free_tiny_fast()` に early-exit を 1 箇所入れる(L1) + +対象: +- `core/front/malloc_tiny_fast.h`(`free_tiny_fast(void* ptr)`) + +差し込み位置: +- header magic / class_idx 確定 +- `base = tiny_user_to_base_inline(ptr)` 取得直後(= 変換点 1 箇所) + +やること: +- `free_tiny_fast_mono_dualhot_enabled()` が ON かつ C0–C3 のときだけ条件判定 +- 条件が揃ったら `tiny_legacy_fallback_free_base(base, class_idx); return 1;` +- それ以外は **既存の `free_tiny_fast()` を完全維持** + +### Patch 3: 見える化(任意・最小) + +対象: +- `core/box/free_path_stats_box.h` + +追加: +- `uint64_t mono_dualhot_hit;` +- direct path で `FREE_PATH_STAT_INC(mono_dualhot_hit);` + +(release では compile-out なので性能外乱なし) + +### Patch 4: A/B 用に cleanenv を拡張(任意) + +対象: +- `scripts/run_mixed_10_cleanenv.sh` + +追加(ENV 漏れ対策): +- `export HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=${HAKMEM_FREE_TINY_FAST_MONO_DUALHOT:-0}` + +## 5. A/B(同一バイナリ) + +### Mixed 10-run(clean env) + +Baseline: +```sh +HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=0 scripts/run_mixed_10_cleanenv.sh +``` + +Optimized: +```sh +HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=1 scripts/run_mixed_10_cleanenv.sh +``` + +判定(Mixed 10-run mean): +- GO: **+1.0% 以上** +- NEUTRAL: **±1.0%** +- NO-GO: **-1.0% 以下** + +### C6-heavy(任意) + +```sh +HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=0 ./bench_mid_large_mt_hakmem 1 1000000 400 1 +HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=1 ./bench_mid_large_mt_hakmem 1 1000000 400 1 +``` + +期待: +- 実質ニュートラル(この Phase は C0–C3 専用のため) + +## 6. 健康診断(必須) + +```sh +scripts/verify_health_profiles.sh +``` + +## 7. 昇格(GO のときだけ) + +- `core/bench_profile.h` + - `MIXED_TINYV3_C7_SAFE` に `bench_setenv_default("HAKMEM_FREE_TINY_FAST_MONO_DUALHOT","1")` を追加 + - 必要なら `C6_HEAVY_LEGACY_POOLV1` は “未設定のまま” で良い(影響が小さいため) +- `CURRENT_TASK.md` に A/B 数値と rollback を追記 + +## 8. Rollback + +- `export HAKMEM_FREE_TINY_FAST_MONO_DUALHOT=0` +