From 7f3ff6c7e66e465edaa251be0fb5d4f1d11f9e85 Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Sun, 14 Dec 2025 01:46:18 +0900 Subject: [PATCH] Phase 4: E1 docs + E2 next instructions --- CURRENT_TASK.md | 60 +++++++++++-------- docs/analysis/ENV_PROFILE_PRESETS.md | 7 +++ ..._E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md | 42 +++++++++---- ...NAPSHOT_CONSOLIDATION_NEXT_INSTRUCTIONS.md | 9 +++ ...E4_E2_ALLOC_PER_CLASS_FASTPATH_1_DESIGN.md | 46 ++++++++++++++ ...OC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md | 52 ++++++++++++++++ hakmem.d | 4 ++ 7 files changed, 185 insertions(+), 35 deletions(-) create mode 100644 docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_1_DESIGN.md create mode 100644 docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 2cde3275..a6783600 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -1,6 +1,36 @@ # 本線タスク(現在) -## 更新メモ(2025-12-14 Phase 4 E1 Next - ENV Snapshot Consolidation) +## 更新メモ(2025-12-14 Phase 4 E1 Complete - ENV Snapshot Consolidation) + +### Phase 4 E1: ENV Snapshot Consolidation ✅ COMPLETE (2025-12-14) + +**Target**: Consolidate 3 ENV gate TLS reads → 1 TLS read +- `tiny_c7_ultra_enabled_env()`: 1.28% self +- `tiny_front_v3_enabled()`: 1.01% self +- `tiny_metadata_cache_enabled()`: 0.97% self +- **Total ENV overhead: 3.26% self** (from perf profile) + +**Implementation**: +- Created `core/box/hakmem_env_snapshot_box.{h,c}` (new ENV snapshot box) +- Migrated 8 call sites across 3 hot path files to use snapshot +- ENV gate: `HAKMEM_ENV_SNAPSHOT=0/1` (default: 0, research box) +- Pattern: Similar to `tiny_front_v3_snapshot` (proven approach) + +**A/B Test Results** (Mixed, 10-run, 20M iters): +- Baseline (E1=0): **43.62M ops/s** (avg), 43.56M ops/s (median) +- Optimized (E1=1): **45.33M ops/s** (avg), 45.31M ops/s (median) +- **Improvement: +3.92% avg, +4.01% median** + +**Decision: GO** (+3.92% >= +2.5% threshold) +- Exceeded conservative expectation (+1-3%) → Achieved +3.92% +- Action: Keep as research box for now (default OFF) +- Commit: `88717a873` + +**Key Insight**: Shifting from shape optimizations (plateaued) to TLS/memory overhead yields strong returns. ENV snapshot consolidation represents new optimization frontier beyond branch prediction tuning. + +### Next: Phase 4 E2 - Alloc Per-Class Fast Path +- 指示書(SSOT): `docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md` +- 設計メモ: `docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_1_DESIGN.md` ### Phase 4 Perf Profiling Complete ✅ (2025-12-14) @@ -9,30 +39,10 @@ - Samples: 922 samples @ 999Hz, 3.1B cycles - Analysis doc: `docs/analysis/PHASE4_PERF_PROFILE_ANALYSIS.md` -**Key Findings**: -1. **ENV Gate Overhead (3.26% combined)**: - - `tiny_c7_ultra_enabled_env()` (1.28%) - - `tiny_front_v3_enabled()` (1.01%) - - `tiny_metadata_cache_enabled()` (0.97%) - - Root cause: 3 separate TLS reads + lazy init checks on every hot path call - -2. **Shape Optimization Plateau**: - - B3 (Routing Shape): +2.89% (initial win) - - D3 (Alloc Gate Shape): +0.56% (NEUTRAL, diminishing returns) - - Lesson: Branch prediction saturation → Next approach should target memory/TLS overhead - -3. **tiny_alloc_gate_fast (15.37% self%)**: - - Route determination: 15.74% (local) - - C7 logging: 17.04% (local, rare in Mixed) - - Opportunity: Per-class fast path specialization (defer to E2) - -**Next Target**: **Phase 4 E1 - ENV Snapshot Consolidation** -- Expected gain: **+3.0-3.5%** (eliminate 3.26% ENV overhead) -- Approach: Consolidate all ENV gates into single TLS snapshot struct -- Precedent: `tiny_front_v3_snapshot` pattern (already proven) -- Cross-cutting: Improves both alloc and free paths -- Next instructions (SSOT): `docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_NEXT_INSTRUCTIONS.md` -- Design memo: `docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md` +**Key Findings Leading to E1**: +1. ENV Gate Overhead (3.26% combined) → **E1 target** +2. Shape Optimization Plateau (B3 +2.89%, D3 +0.56% NEUTRAL) +3. tiny_alloc_gate_fast (15.37% self%) → defer to E2 ### Phase 4 D3: Alloc Gate Shape(HAKMEM_ALLOC_GATE_SHAPE) - ✅ 実装完了(ENV gate + alloc gate 分岐形) diff --git a/docs/analysis/ENV_PROFILE_PRESETS.md b/docs/analysis/ENV_PROFILE_PRESETS.md index de57f898..4cbd8e77 100644 --- a/docs/analysis/ENV_PROFILE_PRESETS.md +++ b/docs/analysis/ENV_PROFILE_PRESETS.md @@ -101,6 +101,13 @@ HAKMEM_ALLOC_GATE_SHAPE=1 ``` - **Status**: NEUTRAL(Mixed 10-run: Mean **+0.56%** / Median **-0.5%**)→ default OFF - **Effect**: `tiny_alloc_gate_fast()` の分岐形を簡素化(`tiny_route_get()` と release logging branch を回避) +- **Phase 4 E1(ENV Snapshot Consolidation)** ✅ GO (opt-in): +```sh +HAKMEM_ENV_SNAPSHOT=1 +``` + - **Status**: ✅ GO(Mixed 10-run: **+3.92% avg / +4.01% median**)→ default OFF(opt-in) + - **Effect**: `tiny_c7_ultra_enabled_env/tiny_front_v3_enabled/tiny_metadata_cache_enabled` のホット ENV gate を snapshot 1 本に集約 + - **Rollback**: `HAKMEM_ENV_SNAPSHOT=0` - v2 系は触らない(C7_SAFE では Pool v2 / Tiny v2 は常時 OFF)。 - FREE_POLICY/THP を触る実験例(現在の HEAD では必須ではなく、組み合わせによっては微マイナスになる場合もある): ```sh diff --git a/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md b/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md index c946185b..e540474c 100644 --- a/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md +++ b/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md @@ -1,5 +1,15 @@ # Phase 4 E1: ENV Snapshot Consolidation(設計メモ) +## Status(2025-12-14) + +- ✅ 実装完了(commit: `88717a873`) +- ✅ Mixed A/B(10-run, iter=20M, ws=400): + - Baseline: **43.62M** ops/s + - Optimized: **45.33M** ops/s + - Gain: **+3.92% avg / +4.01% median** +- 判定: **GO**(目標 +2.5% をクリア) +- 運用: `HAKMEM_ENV_SNAPSHOT=1` は **opt-in(default OFF)** のまま保持(必要ならプリセット昇格) + ## 目的 ホットパスで毎回呼ばれている ENV gate(小さな関数)の呼び出し/分岐/TLS参照を **1 回の “snapshot load” に集約**し、 @@ -54,19 +64,17 @@ MIXED の「shape 最適化の頭打ち」を越える。 ## API(案) ```c +// core/box/hakmem_env_snapshot_box.h typedef struct HakmemEnvSnapshot { - int inited; - int enabled; // ENV: HAKMEM_ENV_SNAPSHOT=0/1(default 0) - - // Hot toggles (effective values) - int tiny_front_v3_enabled; // default 1 - int tiny_c7_ultra_enabled; // default 1 - int tiny_metadata_cache; // default 0 - int tiny_metadata_cache_eff; // tiny_metadata_cache && !learner + bool tiny_c7_ultra_enabled; // ENV: HAKMEM_TINY_C7_ULTRA_ENABLED (default 1) + bool tiny_front_v3_enabled; // ENV: HAKMEM_TINY_FRONT_V3_ENABLED (default 1) + bool tiny_metadata_cache; // ENV: HAKMEM_TINY_METADATA_CACHE (default 0) + bool tiny_metadata_cache_eff; // tiny_metadata_cache && !learner } HakmemEnvSnapshot; -const HakmemEnvSnapshot* hakmem_env_snapshot_get_fast(void); -void hakmem_env_snapshot_refresh_from_env(void); +bool hakmem_env_snapshot_enabled(void); // ENV: HAKMEM_ENV_SNAPSHOT=0/1 (default 0) +const HakmemEnvSnapshot* hakmem_env_snapshot(void); +void hakmem_env_snapshot_refresh_from_env(void); // bench_profile putenv sync ``` 設計ノート: @@ -80,6 +88,16 @@ bench では `bench_setenv_default()` が `putenv()` を使うため、lazy init - `core/bench_profile.h` の最後で `hakmem_env_snapshot_refresh_from_env()` を必ず呼ぶ - `wrapper_env_refresh_from_env()` / `tiny_static_route_refresh_from_env()` と同じ “ENV 同期箱” 扱い +## 実装(置換した call-site) + +- `core/front/malloc_tiny_fast.h`: + - `tiny_c7_ultra_enabled_env()` → snapshot(alloc/free の C7 ULTRA gate) + - `tiny_front_v3_enabled()` → snapshot(free 側 front_snap) +- `core/box/tiny_legacy_fallback_box.h`: + - `tiny_front_v3_enabled()` / `tiny_metadata_cache_enabled()` → snapshot +- `core/box/tiny_metadata_cache_hot_box.h`: + - `tiny_metadata_cache_enabled()` → snapshot(learner interlock を snapshot 側で処理) + ## 移行対象(最小) まずは “毎回評価される” ところを最小パッチで狙う: @@ -114,3 +132,7 @@ bench では `bench_setenv_default()` が `putenv()` を使うため、lazy init - **Learner interlock**: - `tiny_metadata_cache_eff` の計算で learner を必ず抑制 +## 次(Graduate) + +- 追加で 20-run を回し、問題がなければ `MIXED_TINYV3_C7_SAFE` に `HAKMEM_ENV_SNAPSHOT=1` を **プリセット昇格**する(bench default 注入)。 +- rollback は `HAKMEM_ENV_SNAPSHOT=0`(即戻せる)。 diff --git a/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_NEXT_INSTRUCTIONS.md b/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_NEXT_INSTRUCTIONS.md index 1b8c7837..2d854ffc 100644 --- a/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_NEXT_INSTRUCTIONS.md +++ b/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_NEXT_INSTRUCTIONS.md @@ -1,5 +1,11 @@ # Phase 4 E1: ENV Snapshot Consolidation(次の指示書) +## Status(2025-12-14) + +- ✅ GO(commit: `88717a873`) +- Mixed A/B(10-run, iter=20M, ws=400): **+3.92% avg / +4.01% median** +- 現状: opt-in(default OFF)のまま保持 + ## ゴール MIXED の Hot path にある ENV gate 呼び出しを “snapshot 1 回” に集約し、**+2.5% 以上**を狙う。 @@ -96,3 +102,6 @@ E1=1 で perf を取り直し、次を確認: NEUTRAL/NO-GO の場合: - default OFF のまま freeze(本線は汚さない) +## Next(Phase 4 E2) + +- 次の指示書: `docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md` diff --git a/docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_1_DESIGN.md b/docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_1_DESIGN.md new file mode 100644 index 00000000..dae44876 --- /dev/null +++ b/docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_1_DESIGN.md @@ -0,0 +1,46 @@ +# Phase 4 E2: Alloc Per-Class Fast Path(設計メモ) + +## 目的 + +E1 で ENV gate の “TLS/branch 3 本” を潰したあとの次の芯は、 +alloc 側の「class ごとの第2ホット」を勝ち箱にすること。 + +狙い: +- Mixed の alloc ホットで、**C0–C3(小サイズ側)**を “第2ホット” として扱い、 + policy/route の汎用分岐を避けて **LEGACY unified cache へ直行**させる。 + +前提: +- FREE 側は DUALHOT で勝っている(C0–C3 が大量に出る現実がある) +- ALLOC 側は過去に DUALHOT が NO-GO だったが、Phase 2 の SSOT/分岐再配置で “再評価できる状態” になっている + +## 方針(Box Theory) + +- L0: ENV(戻せる) + - `HAKMEM_TINY_ALLOC_DUALHOT=0/1` を “研究箱” から再評価対象へ + - `HAKMEM_ENV_SNAPSHOT=1` と併用(ENV overhead を抑えた状態で判定) + +- L1: Per-class Fast Path(境界 1 箇所) + - `malloc_tiny_fast_for_class()` の **C0–C3 ブロック**でのみ評価する(C4–C7 を汚さない) + - miss のときは **必ず return** で抜けて、後続の policy/route を二重実行しない(過去の失敗原因を再発させない) + +## 成功条件(A/B) + +Mixed 10-run(iter=20M, ws=400, 1T): +- Baseline: `HAKMEM_TINY_ALLOC_DUALHOT=0`(+ E1 は ON) +- Opt: `HAKMEM_TINY_ALLOC_DUALHOT=1`(+ E1 は ON) + +判定: +- GO: mean **+1.0% 以上** +- ±1%: NEUTRAL(freeze) +- -1% 以下: NO-GO(freeze) + +## リスク + +- C0–C3 の割合が小さいワークロードでは効かない(NEUTRAL になりやすい) +- 分岐予測/ICache の影響で回帰する可能性(NO-GO も許容) + +## 次(GO の場合) + +- `MIXED_TINYV3_C7_SAFE` プリセットへ昇格検討(default 注入) +- 併せて perf で `malloc_tiny_fast_for_class` / `tiny_hot_alloc_fast` / `tiny_cold_refill_and_alloc` の変化を確認 + diff --git a/docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md b/docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md new file mode 100644 index 00000000..9ccdc32d --- /dev/null +++ b/docs/analysis/PHASE4_E2_ALLOC_PER_CLASS_FASTPATH_NEXT_INSTRUCTIONS.md @@ -0,0 +1,52 @@ +# Phase 4 E2: Alloc Per-Class Fast Path(次の指示書) + +## Step 0: 前提(E1 を ON にしてから評価) + +E2 は “ENV overhead を消した状態” で効果を見たいので、まず E1 を有効化して測る。 + +推奨: +```sh +HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ENV_SNAPSHOT=1 \ + ./bench_random_mixed_hakmem 20000000 400 1 +``` + +## Step 1: perf で GO 条件(self% ≥ 5%)を満たすか確認 + +```sh +HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ENV_SNAPSHOT=1 perf record -F 99 -- \ + ./bench_random_mixed_hakmem 20000000 400 1 +perf report --stdio --no-children +``` + +メモ: `malloc_tiny_fast_for_class` / `tiny_hot_alloc_fast` / `tiny_cold_refill_and_alloc` が見えていれば GO。 + +## Step 2: A/B(既存スイッチの再評価) + +E2 の最短は “既存の per-class スイッチ” を正しい条件で測ること。 + +Mixed 10-run(iter=20M, ws=400, 1T): +```sh +# Baseline +HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ENV_SNAPSHOT=1 HAKMEM_TINY_ALLOC_DUALHOT=0 \ + ./bench_random_mixed_hakmem 20000000 400 1 + +# Optimized +HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ENV_SNAPSHOT=1 HAKMEM_TINY_ALLOC_DUALHOT=1 \ + ./bench_random_mixed_hakmem 20000000 400 1 +``` + +判定(10-run mean): +- GO: **+1.0% 以上** +- ±1%: NEUTRAL(freeze) +- -1% 以下: NO-GO(freeze) + +## Step 3: GO の場合の昇格 + +- `core/bench_profile.h` の `MIXED_TINYV3_C7_SAFE` に `bench_setenv_default("HAKMEM_TINY_ALLOC_DUALHOT","1");` を入れるか検討 +- `docs/analysis/ENV_PROFILE_PRESETS.md` に結果と rollback を追記 +- `CURRENT_TASK.md` を更新 + +## Step 4: NO-GO/NEUTRAL の場合 + +- E2 は freeze(default OFF) +- 次の候補へ(例: `tiny_region_id_write_header` の hot/cold 化、`tiny_get_max_size` の snapshot 化) diff --git a/hakmem.d b/hakmem.d index 8cf5ed95..7a57b13a 100644 --- a/hakmem.d +++ b/hakmem.d @@ -143,6 +143,7 @@ hakmem.o: core/hakmem.c core/hakmem.h core/hakmem_build_flags.h \ core/box/../front/../box/free_path_stats_box.h \ core/box/../front/../box/tiny_front_hot_box.h \ core/box/../front/../box/tiny_metadata_cache_env_box.h \ + core/box/../front/../box/hakmem_env_snapshot_box.h \ core/box/../front/../box/tiny_ptr_convert_box.h \ core/box/../front/../box/tiny_front_stats_box.h \ core/box/../front/../box/free_path_stats_box.h \ @@ -152,6 +153,7 @@ hakmem.o: core/hakmem.c core/hakmem.h core/hakmem_build_flags.h \ core/box/../front/../box/free_tiny_fast_hotcold_stats_box.h \ core/box/../front/../box/tiny_metadata_cache_hot_box.h \ core/box/../front/../box/tiny_free_route_cache_env_box.h \ + core/box/../front/../box/hakmem_env_snapshot_box.h \ core/box/tiny_alloc_gate_box.h core/box/tiny_route_box.h \ core/box/tiny_alloc_gate_shape_env_box.h \ core/box/tiny_front_config_box.h core/box/wrapper_env_box.h \ @@ -377,6 +379,7 @@ core/box/../front/../box/tiny_front_v3_env_box.h: core/box/../front/../box/free_path_stats_box.h: core/box/../front/../box/tiny_front_hot_box.h: core/box/../front/../box/tiny_metadata_cache_env_box.h: +core/box/../front/../box/hakmem_env_snapshot_box.h: core/box/../front/../box/tiny_ptr_convert_box.h: core/box/../front/../box/tiny_front_stats_box.h: core/box/../front/../box/free_path_stats_box.h: @@ -386,6 +389,7 @@ core/box/../front/../box/free_tiny_fast_hotcold_env_box.h: core/box/../front/../box/free_tiny_fast_hotcold_stats_box.h: core/box/../front/../box/tiny_metadata_cache_hot_box.h: core/box/../front/../box/tiny_free_route_cache_env_box.h: +core/box/../front/../box/hakmem_env_snapshot_box.h: core/box/tiny_alloc_gate_box.h: core/box/tiny_route_box.h: core/box/tiny_alloc_gate_shape_env_box.h: