## Summary Implemented Phase 86 "mask-only commit" optimization for free path: - Bitset mask (0x7f for C0-C6) to identify LEGACY classes - Direct call to tiny_legacy_fallback_free_base_with_env() - No indirect function pointers (avoids Phase 85's -0.86% regression) - Fail-fast on LARSON_FIX=1 (cross-thread validation incompatibility) ## Results (10-run SSOT) **NO-GO**: +0.25% improvement (threshold: +1.0%) - Control: 51,750,467 ops/s (CV: 2.26%) - Treatment: 51,881,055 ops/s (CV: 2.32%) - Delta: +0.25% (mean), -0.15% (median) ## Root Cause Competing optimizations plateau: 1. Phase 9/10 MONO LEGACY (+1.89%) already capture most free path benefit 2. Remaining margin insufficient to overcome: - Two branch checks (mask_enabled + has_class) - I-cache layout tax in hot path - Direct function call overhead ## Phase 85 vs Phase 86 | Metric | Phase 85 | Phase 86 | |--------|----------|----------| | Approach | Indirect calls + table | Bitset mask + direct call | | Result | -0.86% | +0.25% | | Verdict | NO-GO (regression) | NO-GO (insufficient) | Phase 86 correctly avoided indirect call penalties but revealed architectural limit: can't escape Phase 9/10 overlay without restructuring. ## Recommendation Free path optimization layer has reached practical ceiling: - Phase 9/10 +1.89% + Phase 6/19/FASTLANE +16-27% ≈ 18-29% total - Further attempts on ceremony elimination face same constraints - Recommend focus on different optimization layers (malloc, etc.) ## Files Changed ### New - core/box/free_path_legacy_mask_box.h (API + globals) - core/box/free_path_legacy_mask_box.c (refresh logic) ### Modified - core/bench_profile.h (added refresh call) - core/front/malloc_tiny_fast.h (added Phase 86 fast path check) - Makefile (added object files) - CURRENT_TASK.md (documented result) All changes conditional on HAKMEM_FREE_PATH_LEGACY_MASK=1 (default OFF). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2.6 KiB
2.6 KiB
Phase 85: Free Path Commit-Once (LEGACY-only) — Results
Goal
free_tiny_fast() の free path で、**LEGACY に戻るまでの「儀式」(mono/policy/route 計算)**を、
bench_profile 境界で commit-once して hot path から除去する。
- Scope: C4–C7 の LEGACY route のみ
- Reversible:
HAKMEM_FREE_PATH_COMMIT_ONCE=0/1 - Safety:
HAKMEM_TINY_LARSON_FIX=1なら fail-fast で commit 無効
Implementation
- New box:
core/box/free_path_commit_once_fixed_box.hcore/box/free_path_commit_once_fixed_box.c
- Integration:
core/bench_profile.hからfree_path_commit_once_refresh_from_env()を呼ぶcore/front/malloc_tiny_fast.hのfree_tiny_fast()で Phase 9/10 より前に早期ハンドラ dispatch
- Build:
Makefileにcore/box/free_path_commit_once_fixed_box.oを追加
A/B Results (SSOT, 10-run)
Control (HAKMEM_FREE_PATH_COMMIT_ONCE=0)
- Mean: 52.75M ops/s
- Median: 52.94M ops/s
- Min: 51.70M ops/s
- Max: 53.77M ops/s
Treatment (HAKMEM_FREE_PATH_COMMIT_ONCE=1)
- Mean: 52.30M ops/s
- Median: 52.42M ops/s
- Min: 51.04M ops/s
- Max: 53.03M ops/s
Delta: -0.86% (NO-GO)
Diagnosis
1) Phase 10 (MONO LEGACY DIRECT) と最適化内容が被る
既に free_tiny_fast_mono_legacy_direct_enabled() が C4–C7 の直行(policy snapshot をスキップ)を提供しているため、
Phase 85 が「追加で消せる儀式」が薄かった。
結果として、Phase 85 は 追加の gate/table 参照を持ち込み、プラスになりにくい。
2) function pointer dispatch の税
Phase 85 は entry->handler(base, class_idx, env) の 間接呼び出しを導入している。
この種の間接分岐は branch predictor / layout の影響を受けやすく、SSOTでは net で負ける可能性がある。
3) layout tax の可能性
free hot path (free_tiny_fast) へ新規コードを挿入したことで text layout が揺れ、
-0.x% の符号反転が起きやすい(既知パターン)。
Decision
- NO-GO:
HAKMEM_FREE_PATH_COMMIT_ONCEは default OFF の research boxとして保持 - 物理削除はしない(layout tax の符号反転を避けるため)
Follow-ups (if revisiting)
- Handler cache をやめ、commit-once は bitmask (legacy_mask) のみにする(間接 call 排除)。
env snapshotを hot path で取る前に exit できる形を維持し、hot 側は 1本の早期returnに留める。- “置換”は Phase 9/10 を compile-out できる条件が揃った後に Phase 86 で検討(同一バイナリ A/B を優先)。