From dcc1d42e7f7532e64715d39fcf94d603604b048c Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Sun, 14 Dec 2025 17:38:21 +0900 Subject: [PATCH] Phase 6-2: Promote Front FastLane Free DeDup (default ON) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Results: - A/B test: +5.18% on Mixed (10-run, clean env) - Baseline: 46.68M ops/s - Optimized: 49.10M ops/s - Improvement: +2.42M ops/s (+5.18%) Strategy: - Eliminate duplicate header validation in front_fastlane_try_free() - Direct call to free_tiny_fast() when dedup enabled - Single validation path (no redundant checks) Success factors: 1. Complete duplicate elimination (free path optimization) 2. Free path importance (50% of Mixed workload) 3. Improved execution stability (CV: 1.00% → 0.58%) Phase 6 cumulative: - Phase 6-1 FastLane: +11.13% - Phase 6-2 Free DeDup: +5.18% - Total: ~+16-17% from baseline (multiplicative effect) Promotion: - Default: HAKMEM_FRONT_FASTLANE_FREE_DEDUP=1 (opt-out) - Added to MIXED_TINYV3_C7_SAFE preset - Added to C6_HEAVY_LEGACY_POOLV1 preset - Rollback: HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0 Files modified: - core/box/front_fastlane_env_box.h: default 0 → 1 - core/bench_profile.h: added to presets - CURRENT_TASK.md: Phase 6-2 GO result Health check: PASSED (all profiles) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- CURRENT_TASK.md | 20 +- core/bench_profile.h | 8 +- core/box/front_fastlane_box.h | 28 ++- core/box/front_fastlane_env_box.h | 26 +++ ...T_FASTLANE_2_FREE_DEDUP_AB_TEST_RESULTS.md | 209 ++++++++++++++++++ 5 files changed, 281 insertions(+), 10 deletions(-) create mode 100644 docs/analysis/PHASE6_FRONT_FASTLANE_2_FREE_DEDUP_AB_TEST_RESULTS.md diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 41f30f5c..d8e00987 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -16,12 +16,26 @@ - A/B は **同一バイナリで ENV トグル**(削除/追加で別バイナリ比較にしない) - Mixed 10-run は `scripts/run_mixed_10_cleanenv.sh` 基準(ENV 漏れ防止) -### Next: Phase 6-2 FRONT-FASTLANE-FREE-DEDUP(free 側重複排除) +### Phase 6-2 FRONT-FASTLANE-FREE-DEDUP: Front FastLane Free DeDup — ✅ GO / 本線昇格 -狙い: `front_fastlane_try_free()` が `free_tiny_fast()` と **Tiny header 検証を二重に行っている**箇所を削り、free 側の固定費をさらに薄くする。 +結果: Mixed 10-run で **+5.18%**。`front_fastlane_try_free()` の二重ヘッダ検証を排除し、free 側の固定費をさらに削減。 +- A/B 結果: `docs/analysis/PHASE6_FRONT_FASTLANE_2_FREE_DEDUP_AB_TEST_RESULTS.md` - 指示書: `docs/analysis/PHASE6_FRONT_FASTLANE_2_FREE_DEDUP_NEXT_INSTRUCTIONS.md` -- A/B: `HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0/1`(同一バイナリ) +- ENV gate: `HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0/1` (default: 1, opt-out) +- Rollback: `HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0` + +成功要因: +- 重複検証の完全排除(`front_fastlane_try_free()` → `free_tiny_fast()` 直接呼び出し) +- free パスの重要性(Mixed では free が約 50%) +- 実行安定性向上(変動係数 0.58%) + +累積効果(Phase 6): +- Phase 6-1: +11.13% +- Phase 6-2: +5.18% +- **累積**: ベースラインから約 +16-17% の性能向上 + +### Next: TBD(Phase 6 完了、次の芯を検討中) ## 更新メモ(2025-12-14 Phase 5 E5-3 Analysis - Strategic Pivot) diff --git a/core/bench_profile.h b/core/bench_profile.h index 7f632903..b0d6e303 100644 --- a/core/bench_profile.h +++ b/core/bench_profile.h @@ -75,8 +75,10 @@ static inline void bench_apply_profile(void) { bench_setenv_default("HAKMEM_MALLOC_WRAPPER_ENV_SNAPSHOT", "1"); // Phase 5 E5-1: Free Tiny Direct Path (+3.35% proven on Mixed, 10-run) bench_setenv_default("HAKMEM_FREE_TINY_DIRECT", "1"); - // Phase 6: Front FastLane (Layer Collapse) (+11.13% proven on Mixed, 10-run) + // Phase 6-1: Front FastLane (Layer Collapse) (+11.13% proven on Mixed, 10-run) bench_setenv_default("HAKMEM_FRONT_FASTLANE", "1"); + // Phase 6-2: Front FastLane Free DeDup (+5.18% proven on Mixed, 10-run) + bench_setenv_default("HAKMEM_FRONT_FASTLANE_FREE_DEDUP", "1"); // Phase 4-4: C6 ULTRA free+alloc 統合を有効化 (default OFF, manual opt-in) bench_setenv_default("HAKMEM_TINY_C6_ULTRA_FREE_ENABLED", "0"); // Phase MID-V3: Mid/Pool HotBox v3 @@ -104,8 +106,10 @@ static inline void bench_apply_profile(void) { // Phase MID-V3: Mid/Pool HotBox v3 (257-768B, C6 only) bench_setenv_default("HAKMEM_MID_V3_ENABLED", "1"); bench_setenv_default("HAKMEM_MID_V3_CLASSES", "0x40"); - // Phase 6: Front FastLane (Layer Collapse) (+11.13% proven on Mixed, 10-run) + // Phase 6-1: Front FastLane (Layer Collapse) (+11.13% proven on Mixed, 10-run) bench_setenv_default("HAKMEM_FRONT_FASTLANE", "1"); + // Phase 6-2: Front FastLane Free DeDup (+5.18% proven on Mixed, 10-run) + bench_setenv_default("HAKMEM_FRONT_FASTLANE_FREE_DEDUP", "1"); // Phase 2 B3: Routing branch shape optimization (LIKELY on LEGACY, cold helper for rare routes) bench_setenv_default("HAKMEM_TINY_ALLOC_ROUTE_SHAPE", "1"); } else if (strcmp(p, "C6_V7_STUB") == 0) { diff --git a/core/box/front_fastlane_box.h b/core/box/front_fastlane_box.h index b2d0af88..36bc96b0 100644 --- a/core/box/front_fastlane_box.h +++ b/core/box/front_fastlane_box.h @@ -102,9 +102,10 @@ static inline void* front_fastlane_try_malloc(size_t size) { // Hot Inline: try_free // ============================================================================ -// Patch 6: Actual Tiny direct path implementation -// Strategy: Header validation → direct Tiny free (same pattern as E5-1) -// Only handle cases where we have high confidence (Tiny header magic) +// Phase 6-2: Free DeDup optimization +// Strategy: +// - When dedup=1 and class_mask=0xFF: Direct call to free_tiny_fast() (no duplicate header check) +// - Otherwise: Existing header validation path (backward compatible) static inline bool front_fastlane_try_free(void* ptr) { FRONT_FASTLANE_STAT_INC(free_total); @@ -115,6 +116,24 @@ static inline bool front_fastlane_try_free(void* ptr) { } #if HAKMEM_TINY_HEADER_CLASSIDX + // Phase 6-2: DeDup path (eliminate duplicate header validation) + // Conditions: + // 1. Free DeDup enabled (ENV=1) + // 2. All classes enabled (mask=0xFF, no gradual rollout) + if (__builtin_expect(front_fastlane_free_dedup_enabled() && front_fastlane_class_mask() == 0xFF, 1)) { + // Direct call to free_tiny_fast() (handles all validation internally) + // free_tiny_fast() is static inline in malloc_tiny_fast.h, no extern needed + int result = free_tiny_fast(ptr); + if (__builtin_expect(result, 1)) { + FRONT_FASTLANE_STAT_INC(free_hit); + return true; // Handled + } + // Not handled → fallback + FRONT_FASTLANE_STAT_INC(free_fallback_failure); + return false; + } + + // Traditional path (backward compatible, for class mask filtering or dedup=0) // Page boundary guard: ptr must not be page-aligned // (Accessing ptr-1 when ptr is page-aligned could segfault) uintptr_t off = (uintptr_t)ptr & 0xFFFu; @@ -151,8 +170,7 @@ static inline bool front_fastlane_try_free(void* ptr) { // Call existing hot handler (no duplication) // This is the winning path from E5-1 (free_tiny_fast returns 1 on success) - // Forward declaration needed - free_tiny_fast is in malloc_tiny_fast.h - extern int free_tiny_fast(void* ptr); + // free_tiny_fast() is static inline in malloc_tiny_fast.h, no extern needed if (__builtin_expect(free_tiny_fast(ptr), 1)) { FRONT_FASTLANE_STAT_INC(free_hit); return true; // Success diff --git a/core/box/front_fastlane_env_box.h b/core/box/front_fastlane_env_box.h index 2ce04360..3e28ffcc 100644 --- a/core/box/front_fastlane_env_box.h +++ b/core/box/front_fastlane_env_box.h @@ -39,6 +39,7 @@ // Forward declaration for cross-box includes static inline int front_fastlane_enabled(void); static inline uint8_t front_fastlane_class_mask(void); +static inline int front_fastlane_free_dedup_enabled(void); // ============================================================================ // ENV Gate Implementation @@ -95,4 +96,29 @@ static inline uint8_t front_fastlane_class_mask(void) { return (uint8_t)val; } +// Phase 6-2: Free DeDup gate (eliminate duplicate header validation) +// When enabled, front_fastlane_try_free() directly calls free_tiny_fast() +// instead of doing its own header validation. +static inline int front_fastlane_free_dedup_enabled(void) { + static _Atomic int cached = -1; // -1 = uninitialized + int val = atomic_load_explicit(&cached, memory_order_relaxed); + + if (__builtin_expect(val == -1, 0)) { + // Cold path: First call, check ENV + const char* env = getenv("HAKMEM_FRONT_FASTLANE_FREE_DEDUP"); + int enabled = 1; // default: ON (opt-out, +5.18% proven) + + if (env) { + // Parse: "0" or empty = disabled, "1" or non-empty = enabled + enabled = (env[0] != '0' && env[0] != '\0') ? 1 : 0; + } + + // Cache result (thread-safe: atomic store) + atomic_store_explicit(&cached, enabled, memory_order_relaxed); + val = enabled; + } + + return val; +} + #endif // HAK_FRONT_FASTLANE_ENV_BOX_H diff --git a/docs/analysis/PHASE6_FRONT_FASTLANE_2_FREE_DEDUP_AB_TEST_RESULTS.md b/docs/analysis/PHASE6_FRONT_FASTLANE_2_FREE_DEDUP_AB_TEST_RESULTS.md new file mode 100644 index 00000000..c9ed758a --- /dev/null +++ b/docs/analysis/PHASE6_FRONT_FASTLANE_2_FREE_DEDUP_AB_TEST_RESULTS.md @@ -0,0 +1,209 @@ +# Phase 6-2: Front FastLane Free DeDup A/B テスト結果 + +## 概要 + +Phase 6-1 で FastLane(+11.13% GO)により入口固定費を削減した後、Phase 6-2 では **free 側の FastLane 内重複検証を排除** することで、さらなる性能向上を狙った。 + +## 実装内容 + +### Patch 1: Free DeDup ENV gate + +**対象ファイル**: `core/box/front_fastlane_env_box.h` + +追加 API: +- `front_fastlane_free_dedup_enabled(void)` + - ENV: `HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0/1` + - default: **0**(A/B テスト用) + - キャッシュ方式: `static _Atomic int cached=-1` + `getenv`(1回だけ) + +### Patch 2: `front_fastlane_try_free()` を重複なしにする + +**対象ファイル**: `core/box/front_fastlane_box.h` + +戦略: +1. `front_fastlane_free_dedup_enabled()==1` かつ `front_fastlane_class_mask()==0xFF` のとき: + - `free_tiny_fast(ptr)` を **直接呼ぶ**(ヘッダ検証の重複を排除) + - 返り値 `1` → handled(return true) + - `0` → not-handled(return false) +2. それ以外(dedup OFF / class mask を絞っている)では、従来どおり "class mask 判定付き" の経路に残す + +重要な変更: +- `front_fastlane_try_free()` の中にあった `extern int free_tiny_fast(void*)` 宣言を削除 +- `malloc_tiny_fast.h` の `static inline free_tiny_fast()` をそのまま呼ぶ(リンク/インラインの整合) +- `!g_initialized` の Fail-Fast は現状維持 + +## A/B テスト結果 + +### 環境 +- プロファイル: `MIXED_TINYV3_C7_SAFE` +- イテレーション: 20,000,000 +- ワーキングセット: 400 +- 実行回数: 10 runs(各設定) + +### OFF(HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0) + +``` +Run 1: 47365474 ops/s +Run 2: 46469536 ops/s +Run 3: 45532401 ops/s +Run 4: 46777467 ops/s +Run 5: 46884997 ops/s +Run 6: 46760221 ops/s +Run 7: 47011298 ops/s +Run 8: 46594185 ops/s +Run 9: 46802184 ops/s +Run 10: 46602521 ops/s +``` + +統計: +- **平均値**: 46,680,028 ops/s +- **中央値**: 46,769,344 ops/s +- **標準偏差**: 467,456 ops/s +- **変動係数**: 1.00% + +### ON(HAKMEM_FRONT_FASTLANE_FREE_DEDUP=1) + +``` +Run 1: 49614395 ops/s +Run 2: 49380243 ops/s +Run 3: 49085005 ops/s +Run 4: 48691723 ops/s +Run 5: 48957465 ops/s +Run 6: 49151771 ops/s +Run 7: 48770929 ops/s +Run 8: 48906449 ops/s +Run 9: 49278301 ops/s +Run 10: 49158759 ops/s +``` + +統計: +- **平均値**: 49,099,504 ops/s +- **中央値**: 49,119,765 ops/s +- **標準偏差**: 287,163 ops/s +- **変動係数**: 0.58% + +## 性能差分 + +### 絶対値 +- **差分**: +2,419,476 ops/s +- **改善率**: **+5.18%** + +### パーセンテージ +- OFF 平均: 46,680,028 ops/s +- ON 平均: 49,099,504 ops/s +- **改善**: **+5.18%** ← **GO 判定** + +## 判定 + +### 判定基準(Mixed 10-run mean) +- GO: **+1.0% 以上** ✅ +- NEUTRAL: **±1.0%** +- NO-GO: **-1.0% 以下** + +### 結果 +**判定: GO (+5.18%)** + +Phase 6-2 Free DeDup は **明確な性能向上(+5.18%)** を達成し、GO 判定となった。 + +## 分析 + +### 成功要因 + +1. **重複検証の排除**: + - `front_fastlane_try_free()` が自前でヘッダ検証をしていた + - `free_tiny_fast()` も同じ検証を実行していた + - DeDup ON で `free_tiny_fast()` を直接呼ぶことで、重複を完全に排除 + +2. **free パスの重要性**: + - Mixed workload では free が支配的(50%) + - free 側の最適化は malloc 側よりも効果が大きい傾向 + - 今回の +5.18% は free 重複排除による直接的な効果 + +3. **ブランチヒントの効果**: + - `__builtin_expect(front_fastlane_free_dedup_enabled() && front_fastlane_class_mask() == 0xFF, 1)` + - DeDup ON のときは高速パスが LIKELY となり、CPU 分岐予測が最適化される + +### 低い変動係数 + +- OFF: 1.00% +- ON: 0.58% + +ON の方が変動が少ない理由: +- ブランチが減ることで、実行パスが単純化 +- I-cache/分岐予測の一貫性が向上 +- タイミングの安定性が増加 + +## 健康診断 + +```bash +scripts/verify_health_profiles.sh +``` + +結果: **OK: health profiles passed** + +- `MIXED_TINYV3_C7_SAFE`: 47,762,207 ops/s +- `C6_HEAVY_LEGACY_POOLV1`: 22,884,419 ops/s + +両方のプロファイルで正常動作を確認。 + +## 次のステップ(昇格) + +### 1. default を ON に変更 + +`core/box/front_fastlane_env_box.h`: +```c +int enabled = 1; // default: ON (opt-out) +``` + +### 2. 主要プロファイルで ENV 設定 + +`core/bench_profile.h` の主要プロファイルで: +```c +bench_setenv_default("HAKMEM_FRONT_FASTLANE_FREE_DEDUP","1") +``` + +### 3. CURRENT_TASK.md に記録 + +```markdown +## Phase 6-2: Front FastLane Free DeDup (GO, +5.18%) + +- **日時**: 2025-XX-XX +- **A/B 結果**: OFF=46.68M ops/s → ON=49.10M ops/s (+5.18%) +- **判定**: GO +- **昇格**: default=1, opt-out via `HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0` +- **Rollback**: `HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0` +``` + +## Rollback 手順(即戻せる) + +Phase 6-2 だけ戻す: +```bash +export HAKMEM_FRONT_FASTLANE_FREE_DEDUP=0 +``` + +FastLane 全体を戻す(Phase 6-1 も含む): +```bash +export HAKMEM_FRONT_FASTLANE=0 +``` + +## まとめ + +Phase 6-2 Free DeDup は **+5.18%** の明確な性能向上を達成し、GO 判定となった。 + +累積効果: +- Phase 6-1 FastLane: +11.13% +- Phase 6-2 Free DeDup: +5.18% +- **累積**: ベースラインから約 **+16-17%** の性能向上(乗算効果) + +次のステップ: +1. default を ON に昇格 +2. 主要プロファイルで ENV 設定 +3. CURRENT_TASK.md に記録 +4. 次の最適化フェーズへ進む + +--- + +**作成日**: 2025-12-14 +**Phase**: 6-2 +**判定**: GO (+5.18%) +**ステータス**: 昇格準備完了