2025-12-14 07:18:59 +09:00
|
|
|
|
# Phase 5 E6: ENV Snapshot Branch-Shape Fix(結果: NO-GO / FROZEN)
|
|
|
|
|
|
|
|
|
|
|
|
## Status(2025-12-14)
|
|
|
|
|
|
|
|
|
|
|
|
- 結果: **NO-GO**(Mixed: **-1.71%**)
|
|
|
|
|
|
- 理由: 二重分岐で branch 数/コードサイズが増え、mispredict 改善が吸収できない
|
|
|
|
|
|
- 対応: **freeze**(追わない)
|
|
|
|
|
|
- 参考: `docs/analysis/PHASE5_E6_ENV_SNAPSHOT_SHAPE_AB_TEST_RESULTS.md`
|
|
|
|
|
|
|
|
|
|
|
|
注意:
|
|
|
|
|
|
- E6 の “実装” は hot path を肥大化させるため、本線からは外す(doc だけ残すのが安全)。
|
2025-12-14 06:59:35 +09:00
|
|
|
|
|
|
|
|
|
|
## 背景(E5-2 / E5-4 連続 NEUTRAL 後)
|
|
|
|
|
|
|
|
|
|
|
|
- `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE` では `HAKMEM_ENV_SNAPSHOT=1` が常用。
|
|
|
|
|
|
- しかし hot path 側(例: `malloc_tiny_fast_for_class()`)に
|
|
|
|
|
|
`if (__builtin_expect(hakmem_env_snapshot_enabled(), 0))` のような “OFF 前提” hint が残っている。
|
|
|
|
|
|
- これは **steady-state で毎回 mispredict** になり得る(enabled が真のとき)。
|
|
|
|
|
|
|
|
|
|
|
|
狙い:
|
|
|
|
|
|
- 意味(semantic)は一切変えず、**分岐形だけ**を “enabled 前提” に寄せる。
|
|
|
|
|
|
- ただし default build では `HAKMEM_ENV_SNAPSHOT=0` もあり得るので、**MIXED のみ opt-in** に限定する(戻せる)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Box Theory(箱の切り方)
|
|
|
|
|
|
|
|
|
|
|
|
- L0: `env_snapshot_shape_enabled()`(ENV gate, default OFF)
|
|
|
|
|
|
- L1: “shape 変更” は call site だけ(境界 1 箇所ずつ)
|
|
|
|
|
|
- Fail-fast: なし(意味不変なので)
|
|
|
|
|
|
- 見える化: perf / branch-misses のみ(常時ログ禁止)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Step 1: ENV gate を追加
|
|
|
|
|
|
|
|
|
|
|
|
新規:
|
|
|
|
|
|
- `core/box/env_snapshot_shape_env_box.h`
|
|
|
|
|
|
- ENV: `HAKMEM_ENV_SNAPSHOT_SHAPE=0/1`(default 0)
|
|
|
|
|
|
- `static inline bool env_snapshot_shape_enabled(void)`
|
|
|
|
|
|
|
|
|
|
|
|
有効化ポリシー:
|
|
|
|
|
|
- `MIXED_TINYV3_C7_SAFE` でのみ `bench_setenv_default("HAKMEM_ENV_SNAPSHOT_SHAPE","1")` を検討(GO 後)
|
|
|
|
|
|
- 他プロファイルは default OFF のまま
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Step 2: call site を “enabled 前提” の形に変更(意味不変)
|
|
|
|
|
|
|
|
|
|
|
|
対象(例):
|
|
|
|
|
|
- `core/front/malloc_tiny_fast.h` 内の複数箇所
|
|
|
|
|
|
- `core/box/tiny_metadata_cache_hot_box.h`
|
|
|
|
|
|
- `core/box/tiny_legacy_fallback_box.h`
|
|
|
|
|
|
|
|
|
|
|
|
置換パターン:
|
|
|
|
|
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
```c
|
|
|
|
|
|
if (__builtin_expect(hakmem_env_snapshot_enabled(), 0)) {
|
|
|
|
|
|
const HakmemEnvSnapshot* env = hakmem_env_snapshot();
|
|
|
|
|
|
x = env->tiny_c7_ultra_enabled;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
x = tiny_c7_ultra_enabled_env();
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
After(shape gate ON のときだけ形を変える):
|
|
|
|
|
|
```c
|
|
|
|
|
|
if (__builtin_expect(env_snapshot_shape_enabled(), 0)) {
|
|
|
|
|
|
if (__builtin_expect(!hakmem_env_snapshot_enabled(), 0)) {
|
|
|
|
|
|
x = tiny_c7_ultra_enabled_env();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const HakmemEnvSnapshot* env = hakmem_env_snapshot();
|
|
|
|
|
|
x = env->tiny_c7_ultra_enabled;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (__builtin_expect(hakmem_env_snapshot_enabled(), 0)) {
|
|
|
|
|
|
const HakmemEnvSnapshot* env = hakmem_env_snapshot();
|
|
|
|
|
|
x = env->tiny_c7_ultra_enabled;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
x = tiny_c7_ultra_enabled_env();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
注意:
|
|
|
|
|
|
- `HAKMEM_ENV_SNAPSHOT=0` のときに mispredict が増えないよう、shape は **MIXED だけ**で使う。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Step 3: A/B(Mixed 10-run)
|
|
|
|
|
|
|
|
|
|
|
|
### A: shape OFF
|
|
|
|
|
|
```sh
|
|
|
|
|
|
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
|
|
|
|
|
HAKMEM_ENV_SNAPSHOT=1 \
|
|
|
|
|
|
HAKMEM_ENV_SNAPSHOT_SHAPE=0 \
|
|
|
|
|
|
./bench_random_mixed_hakmem 20000000 400 1
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### B: shape ON
|
|
|
|
|
|
```sh
|
|
|
|
|
|
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
|
|
|
|
|
HAKMEM_ENV_SNAPSHOT=1 \
|
|
|
|
|
|
HAKMEM_ENV_SNAPSHOT_SHAPE=1 \
|
|
|
|
|
|
./bench_random_mixed_hakmem 20000000 400 1
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
判定:
|
|
|
|
|
|
- GO: mean **+1.0% 以上**
|
|
|
|
|
|
- ±1.0%: NEUTRAL → freeze
|
|
|
|
|
|
- -1.0% 以下: NO-GO → freeze
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Step 4: branch-miss を確認(任意)
|
|
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
|
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
|
|
|
|
|
HAKMEM_ENV_SNAPSHOT=1 HAKMEM_ENV_SNAPSHOT_SHAPE=0 \
|
|
|
|
|
|
perf stat -e branches,branch-misses -- \
|
|
|
|
|
|
./bench_random_mixed_hakmem 20000000 400 1
|
|
|
|
|
|
|
|
|
|
|
|
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
|
|
|
|
|
HAKMEM_ENV_SNAPSHOT=1 HAKMEM_ENV_SNAPSHOT_SHAPE=1 \
|
|
|
|
|
|
perf stat -e branches,branch-misses -- \
|
|
|
|
|
|
./bench_random_mixed_hakmem 20000000 400 1
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
期待:
|
|
|
|
|
|
- `branch-misses` が下がる(throughput も上がるのが理想)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Step 5: 健康診断
|
|
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
|
scripts/verify_health_profiles.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Step 6: 昇格(GO のときだけ)
|
|
|
|
|
|
|
|
|
|
|
|
- `core/bench_profile.h`(MIXED):
|
|
|
|
|
|
- `bench_setenv_default("HAKMEM_ENV_SNAPSHOT_SHAPE","1")`
|
|
|
|
|
|
- `docs/analysis/ENV_PROFILE_PRESETS.md` に A/B と rollback(`=0`)追記
|
|
|
|
|
|
- `CURRENT_TASK.md` を更新
|