Files
hakmem/docs/analysis/PHASE4_E1_ENV_SNAPSHOT_CONSOLIDATION_1_DESIGN.md
2025-12-14 01:46:18 +09:00

5.9 KiB
Raw Blame History

Phase 4 E1: ENV Snapshot Consolidation設計メモ

Status2025-12-14

  • 実装完了commit: 88717a873
  • Mixed A/B10-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=1opt-indefault OFF のまま保持(必要ならプリセット昇格)

目的

ホットパスで毎回呼ばれている ENV gate小さな関数の呼び出し分岐TLS参照を 1 回の “snapshot load” に集約し、 MIXED の「shape 最適化の頭打ち」を越える。

ターゲット(直近 perf self%:

  • tiny_c7_ultra_enabled_env() ≈ 1.28%
  • tiny_front_v3_enabled() ≈ 1.01%
  • tiny_metadata_cache_enabled() ≈ 0.97%
  • 合計 ≈ 3.26%

※ self% はそのまま speedup にはならないが、Hot loop で “毎回” 評価される小関数群が占める割合として無視できない。

背景(何が起きているか)

  • Phase 23 の “分岐形shape” 最適化は一定効いたが、D3 が NEUTRAL になり 形だけでは頭打ち
  • 現状は「ENV gate を 3 回別々に呼ぶ」ため、
    • 小関数 callinlining されないケース)
    • lazy init の分岐TU-local static / probe window
    • TLS 参照policy hot TLS 等) が積み上がる。
  • さらに __builtin_expect(..., 0)実態default ONと逆の場所があり、分岐予測を損ねている可能性が高い。

非目標

  • ルーティングやアルゴリズムの変更(意味を変えない)
  • Learner の挙動変更interlock を壊さない)
  • 常時ログ増加(ワンショット/統計のみ)

箱割りBox Theory

L0: EnvSnapshotBox設定を 1 箱に集約)

新規 Box:

  • core/box/hakmem_env_snapshot_box.h
  • core/box/hakmem_env_snapshot_box.c

責務:

  • ENV を 1 回だけ読んで “Hot に必要な bool 値” を構造体に凍結する
  • bench_profile の putenv() 後に refresh できる(戻せる)

L1: Call-site Migration境界 1 箇所ずつ置換)

既存の ENV gate を “呼ばない” 方向で、以下の call-site を段階的に置換する。 (既存 gate 関数は残し、E1 を OFF に戻せる)

対象(最小セット):

  • tiny_c7_ultra_enabled_env() → snapshot フィールド参照
  • tiny_front_v3_enabled() → snapshot フィールド参照or snapshot から front_snap を得る)
  • tiny_metadata_cache_enabled() → snapshot フィールド参照learner interlock を含んだ “effective” 値)

API

// core/box/hakmem_env_snapshot_box.h
typedef struct HakmemEnvSnapshot {
    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;

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

設計ノート:

  • *_eff を持たせ、call-site から small_learner_v2_enabled() の呼び出しを除去する
  • enabled は refresh 時に 1 回だけ決め、Hot では分岐を増やさない(できれば compile-out

初期化と bench_profileputenv 問題)

bench では bench_setenv_default()putenv() を使うため、lazy init が先に走ると “誤った 0” を掴む。 対策は既存方針に合わせる:

  • 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() → snapshotalloc/free の C7 ULTRA gate
    • tiny_front_v3_enabled() → snapshotfree 側 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() → snapshotlearner interlock を snapshot 側で処理)

移行対象(最小)

まずは “毎回評価される” ところを最小パッチで狙う:

  • core/front/malloc_tiny_fast.halloc/free の hot path
  • core/box/tiny_legacy_fallback_box.hfree の第2ホット
  • core/box/tiny_metadata_cache_hot_box.hpolicy hot 入口)
  • core/box/free_policy_fast_v2_box.h(研究箱だが整合)

A/BGO/NO-GO

ベンチ

  • Mixed10-run, iter=20M, ws=400, 1T
    • Baseline: HAKMEM_ENV_SNAPSHOT=0
    • Opt: HAKMEM_ENV_SNAPSHOT=1

判定

  • GO: mean +2.5% 以上(目標) かつ crash/assert なし
  • NEUTRAL: ±1% 以内 → research box 維持default OFF
  • NO-GO: -1% 以下 → freeze

検証(必須)

  • perf で tiny_c7_ultra_enabled_env/tiny_front_v3_enabled/tiny_metadata_cache_enabled の self% が 明確に減ること
  • 本線プロファイルMIXED_TINYV3_C7_SAFEで regression がないこと

リスクと回避

  • MEDIUMrefactor/置換):
    • 置換は “最小 3 gate” から始め、段階的に広げる
    • 失敗したら HAKMEM_ENV_SNAPSHOT=0 で即戻す
  • 初期化順序:
    • bench_profile に refresh を追加して putenv 後の SSOT を保証
  • Learner interlock:
    • tiny_metadata_cache_eff の計算で learner を必ず抑制

Graduate

  • 追加で 20-run を回し、問題がなければ MIXED_TINYV3_C7_SAFEHAKMEM_ENV_SNAPSHOT=1プリセット昇格するbench default 注入)。
  • rollback は HAKMEM_ENV_SNAPSHOT=0(即戻せる)。