Step 0: Geometry SSOT
- New: core/box/smallobject_mid_v35_geom_box.h (L1/L2 consistency)
- Fix: C6 slots/page 102→128 in L2 (smallobject_cold_iface_mid_v3.c)
- Applied: smallobject_mid_v35.c, smallobject_segment_mid_v3.c
Step 1-3: ENV gates for hotpath optimizations
- New: core/box/mid_v35_hotpath_env_box.h
* HAKMEM_MID_V35_HEADER_PREFILL (default 0)
* HAKMEM_MID_V35_HOT_COUNTS (default 1)
* HAKMEM_MID_V35_C6_FASTPATH (default 0)
- Implementation: smallobject_mid_v35.c
* Header prefill at refill boundary (Step 1)
* Gated alloc_count++ in hot path (Step 2)
* C6 specialized fast path with constant slot_size (Step 3)
A/B Results:
C6-heavy (257–768B): 8.75M→9.39M ops/s (+7.3%, 5-run mean) ✅
Mixed (16–1024B): 9.98M→9.96M ops/s (-0.2%, within noise) ✓
Decision: FROZEN - defaults OFF, C6-heavy推奨ON, Mixed現状維持
Documentation: ENV_PROFILE_PRESETS.md updated
🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
17 KiB
17 KiB
ENV Profile Presets (HAKMEM)
よく使う構成を 3 つのプリセットにまとめました。まずここからコピペし、必要な ENV だけを追加してください。v2 系や LEGACY 専用オプションは明示 opt-in で扱います。
ベンチバイナリでは HAKMEM_PROFILE=<名前> をセットすると、ここで定義した ENV を自動で注入します(既に設定済みの ENV は上書きしません)。
Profile 1: MIXED_TINYV3_C7_SAFE(標準 Mixed 16–1024B)
目的
- Mixed 16–1024B の標準ベンチ用。
- C7-only SmallObject v3 + Tiny front v3 + LUT + fast classify ON。
- v4 系(C6/C7 v4、fast classify v4、small segment v4)はすべて OFF。
- Tiny/Pool v2 もすべて OFF。
- v7 (C5/C6) は OFF (Phase v10: Mixed 本線では v7 無効化、C5/C6 専用プリセット参照)
- C6 は凍結中(Tiny/SmallObject の特別扱いなし)。mid/pool の通常経路に任せる。
ENV 最小セット(Release)
# プリセットでまとめて指定
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE
# Mixed 16–1024B 前提のサイズ範囲(必要に応じて明示)
HAKMEM_BENCH_MIN_SIZE=16
HAKMEM_BENCH_MAX_SIZE=1024
プリセットで自動設定される主な ENV:
HAKMEM_TINY_HEAP_PROFILE=C7_SAFEHAKMEM_TINY_C7_HOT=1HAKMEM_TINY_HOTHEAP_V2=0HAKMEM_SMALL_HEAP_V3_ENABLED=1HAKMEM_SMALL_HEAP_V3_CLASSES=0x80(C7-only v3)HAKMEM_SMALL_HEAP_V4_ENABLED=0/HAKMEM_SMALL_HEAP_V4_CLASSES=0x0HAKMEM_TINY_PTR_FAST_CLASSIFY_ENABLED=1HAKMEM_TINY_PTR_FAST_CLASSIFY_V4_ENABLED=0HAKMEM_SMALL_SEGMENT_V4_ENABLED=0HAKMEM_POOL_V2_ENABLED=0HAKMEM_TINY_FRONT_V3_ENABLED=1HAKMEM_TINY_FRONT_V3_LUT_ENABLED=1HAKMEM_MID_V3_ENABLED=1(Phase MID-V3: 257-768B, C6 only)HAKMEM_MID_V3_CLASSES=0x40(C6 only, C7 は ULTRA に任せる)HAKMEM_MID_V35_ENABLED=0(Phase v11a-5: Mixed では MID v3.5 OFF が最速)
任意オプション
- stats を見たいとき:
HAKMEM_TINY_HEAP_STATS=1
HAKMEM_TINY_HEAP_STATS_DUMP=1
HAKMEM_SMALL_HEAP_V3_STATS=1
- Phase MID-V35-HOTPATH-OPT-1 (FROZEN - research only):
HAKMEM_MID_V35_HEADER_PREFILL=1 # refill境界でheader先行書き
HAKMEM_MID_V35_HOT_COUNTS=0 # alloc_count削除
HAKMEM_MID_V35_C6_FASTPATH=1 # C6特化 fast path
- Status: Default OFF, FROZEN (all 3 knobs)
- Actual Results (Phase MID-V35-HOTPATH-OPT-1 Mixed A/B):
- Mixed (16–1024B, MID_V35_OFF): -0.2% (誤差範囲, ±2%以内) ✓
- C6-heavy (257–768B, MID_V35_ON): +7.3% improvement ✅
- Finding: Mixed は MID_V3(C6-only) 固定で効果微小;C6-heavy のみ効果大
- Recommendation: C6_HEAVY_LEGACY_POOLV1 プリセットで推奨ON
- NOT recommended for: MIXED_TINYV3_C7_SAFE mainline (keep all defaults OFF)
- Phase POLICY-FAST-PATH-V2 (FROZEN - research only):
HAKMEM_TINY_FREE_POLICY_FAST_V2=1 # Fast-path free optimization
- Status: Default OFF, FROZEN (merge complete)
- Actual Results (Phase POLICY-FAST-PATH-V2 A/B):
- Mixed (ws=400): -1.6% regression ❌ (added branch cost > skip benefit)
- C6-heavy (ws=200): +5.4% improvement ✅
- Finding: Large working set (ws>300) causes branch misprediction cost to dominate
- Recommendation: Use only for C6-heavy or ws<300 research benchmarks
- NOT recommended for: MIXED_TINYV3_C7_SAFE mainline (keep OFF)
- Requirement: Only effective when v7 Learner is disabled
- v2 系は触らない(C7_SAFE では Pool v2 / Tiny v2 は常時 OFF)。
- FREE_POLICY/THP を触る実験例(現在の HEAD では必須ではなく、組み合わせによっては微マイナスになる場合もある):
HAKMEM_FREE_POLICY=keep
HAKMEM_DISABLE_BATCH=1
HAKMEM_SS_MADVISE_STRICT=0
# or
HAKMEM_FREE_POLICY=batch
HAKMEM_THP=auto
- 参考(v4 研究箱の現状):
- C7/C6 v4 + fast classify v4 ON(v3 OFF, segment OFF): ≈32.0–32.5M ops/s(MIXED 1M/ws=400, Release)。
- C7-only v4(C6 v1、v3 OFF): ≈33.0M ops/s。
- 現状は v3 構成が最速のため、標準プロファイルでは v4 系をすべて OFF に固定。
Profile 2: C6_HEAVY_LEGACY_POOLV1(mid/smallmid C6-heavy ベンチ)
目的
- C6-heavy mid/smallmid のベンチ用。
- C6 は v1 固定(C6 v3/v4/ULTRA は研究箱のみ)。Pool v2 OFF。Pool v1 flatten は bench 用に opt-in。
ENV(v1 基準線 + MID v3)
HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1
# または直接指定:
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
HAKMEM_TINY_HEAP_PROFILE=C7_SAFE
HAKMEM_TINY_C6_HOT=0
HAKMEM_TINY_HOTHEAP_V2=0
HAKMEM_SMALL_HEAP_V3_ENABLED=1
HAKMEM_SMALL_HEAP_V3_CLASSES=0x80 # C7-only v3, C6 v3 は OFF
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_POOL_V1_FLATTEN_ENABLED=0 # flatten は初回 OFF
HAKMEM_MID_V3_ENABLED=1 # Phase MID-V3: 257-768B, C6 only
HAKMEM_MID_V3_CLASSES=0x40 # C6 only (+11% on C6-heavy)
HAKMEM_MID_V35_ENABLED=1 # Phase v11a-5: C6-heavy で +8% 改善
HAKMEM_MID_V35_CLASSES=0x40 # C6 only (53.1M ops/s)
# Phase MID-V35-HOTPATH-OPT-1: C6-heavy 最速セット(推奨ON)
# 機能: header prefill + hot counts削除 + C6 fast path (組み合わせで +7.3%)
HAKMEM_MID_V35_HEADER_PREFILL=1 # refill境界でheader先行書き
HAKMEM_MID_V35_HOT_COUNTS=0 # alloc_count削除(free_count/retire残す)
HAKMEM_MID_V35_C6_FASTPATH=1 # C6特化 fast path (constant slot_size=512)
- mid_desc_lookup TLS キャッシュを試すときだけ:
HAKMEM_MID_DESC_CACHE_ENABLED=1を上乗せ(デフォルトは OFF)。
Pool v1 flatten A/B 用(LEGACY 専用)
# LEGACY + flatten ON (研究/bench専用)
HAKMEM_TINY_HEAP_PROFILE=LEGACY
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_POOL_V1_FLATTEN_ENABLED=1
HAKMEM_POOL_V1_FLATTEN_STATS=1
Profile 2b: C6_HEAVY_LEGACY_POOLV1_FLATTEN(mid/smallmid LEGACY flatten ベンチ専用)
目的
- LEGACY プロファイルで mid/smallmid の flatten + header-only zero をまとめて opt-in するベンチ専用セット。
- C7_SAFE では使わないこと(安定性優先のため C7_SAFE は flatten 常時 OFF)。
ENV(ベンチ専用)
HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 # base を流用
HAKMEM_POOL_V1_FLATTEN_ENABLED=1
HAKMEM_POOL_ZERO_MODE=header
HAKMEM_POOL_V1_FLATTEN_STATS=1
※ LEGACY 専用。C7_SAFE / C7_ULTRA_BENCH ではこのプリセットを使用しないこと。
- flatten は LEGACY 専用。C7_SAFE / C7_ULTRA_BENCH ではコード側で強制 OFF になる前提。
C6 研究用プリセット(標準ラインには影響させない)
- C6 v3 研究(Tiny/SmallObject に C6 を載せるときだけ)
HAKMEM_PROFILE=C6_SMALL_HEAP_V3_EXPERIMENT
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
# bench_profile が以下を自動注入(既存 ENV を上書きしません):
# HAKMEM_TINY_C6_HOT=1
# HAKMEM_SMALL_HEAP_V3_ENABLED=1
# HAKMEM_SMALL_HEAP_V3_CLASSES=0x40 # C6 only v3
- C6 v4 研究(C6 を v4 に載せるときだけ)
HAKMEM_PROFILE=C6_SMALL_HEAP_V4_EXPERIMENT
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
# bench_profile が以下を自動注入(既存 ENV を上書きしません):
# HAKMEM_TINY_C6_HOT=1
# HAKMEM_SMALL_HEAP_V3_ENABLED=0
# HAKMEM_SMALL_HEAP_V4_ENABLED=1
# HAKMEM_SMALL_HEAP_V4_CLASSES=0x40 # C6 only v4
※ いずれも「研究箱」です。Mixed/C6-heavy の標準評価では使わず、回帰やセグフォを許容できるときだけ明示的に opt-in してください。
Research Profile 0: C6_SMALL_HEAP_V5_STUB(SmallObject v5 C6-only route stub, Phase v5-1)
目的
- C6-only を SmallObject v5 route に載せるベンチ専用(v5-1 段階では挙動は v1/pool fallback)。
- ENV gate(HAKMEM_SMALL_HEAP_V5_ENABLED=1, HAKMEM_SMALL_HEAP_V5_CLASSES=0x40)で route 制御。
- front 経由で v5 通電確認&sanity テスト(実装は v5-2 以降)。
- Mixed/C6-heavy で v1 baseline と同じ perf を期待。
ENV(v5 C6-only opt-in)
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
HAKMEM_TINY_HEAP_PROFILE=C7_SAFE
HAKMEM_TINY_C6_HOT=0
HAKMEM_TINY_HOTHEAP_V2=0
HAKMEM_SMALL_HEAP_V3_ENABLED=1
HAKMEM_SMALL_HEAP_V3_CLASSES=0x80 # C7-only v3(C6 は v3 OFF)
HAKMEM_SMALL_HEAP_V5_ENABLED=1 # ★ v5 ON
HAKMEM_SMALL_HEAP_V5_CLASSES=0x40 # ★ C6(bit6) だけ v5 route に
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_POOL_V1_FLATTEN_ENABLED=0
テストコマンド
export HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1
export HAKMEM_SMALL_HEAP_V5_ENABLED=1
export HAKMEM_SMALL_HEAP_V5_CLASSES=0x40
./bench_random_mixed_hakmem 256 512 100 # C6 size range
./bench_mid_large_mt_hakmem 1 1000000 400 1 # pool baseline comparison
期待値
- Throughput ≈ v1 baseline(変化なし、v1 fallback の為)
- segv/assert なし
- route snapshot で C6 → TINY_ROUTE_SMALL_HEAP_V5 に分岐確認
注意
- v5-1 では中身は v1/pool fallback のまま(実装は v5-2)
- 本線には載せない、研究箱扱い
Research Profile 1: C6_ONLY_SMALLOBJECT_V4(SmallObject v4 C6-only 試運転)
目的
- C6-only を SmallObject v4 route に載せて、page_meta_of() の試運転。
- 挙動はまだ pool v1 fallback のため、perf は v1 固定と同じ。
- Phase v4-mid-1: page_meta_of() が落ちないか、segv/assert なしか確認する研究ベンチ。
ENV(v4 C6-only opt-in)
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
HAKMEM_TINY_HEAP_PROFILE=C7_SAFE
HAKMEM_TINY_C6_HOT=0
HAKMEM_TINY_HOTHEAP_V2=0
HAKMEM_SMALL_HEAP_V3_ENABLED=1
HAKMEM_SMALL_HEAP_V3_CLASSES=0x80 # C7-only v3(C6 は v3 OFF)
HAKMEM_SMALL_HEAP_V4_ENABLED=1 # ★ v4 ON
HAKMEM_SMALL_HEAP_V4_CLASSES=0x40 # ★ C6(bit6) だけ v4 route に
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_POOL_V1_FLATTEN_ENABLED=0
テストコマンド
export HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1
export HAKMEM_SMALL_HEAP_V4_ENABLED=1
export HAKMEM_SMALL_HEAP_V4_CLASSES=0x40
./bench_mid_large_mt_hakmem 1000000 400 1
期待値
- Throughput ≈ 28–29M ops/s(v1 基線の ≈28M と同じ)
- segv/assert なし
- small_segment_v4_page_meta_of(ptr) が動く(debug output で確認可能)
注意
- 実際の alloc/free 動作は pool v1 のまま(v4 freelist は使わない)
- Phase v4-mid-2 で本格実装時に差し替える
Research Profile 2: C7_C6_V4_EXPERIMENT(C7+C6 v4 統合研究)
目的
- 後続フェーズで C7+C6 両者を v4 に載せるときの参考プリセット。
- 現フェーズではまだ使わない(v4-mid-1 は C6-only)。
ENV(参考用)
HAKMEM_BENCH_MIN_SIZE=16
HAKMEM_BENCH_MAX_SIZE=1024
HAKMEM_SMALL_HEAP_V4_ENABLED=1
HAKMEM_SMALL_HEAP_V4_CLASSES=0xC0 # C6(0x40) + C7(0x80)
Profile 3: DEBUG_TINY_FRONT_PERF(perf 用 DEBUG プロファイル)
目的
- Tiny front v3(C7 v3 含む)の perf record 用。
- -O0 / -g / LTO OFF でシンボル付き計測。
ビルド例
make clean
CFLAGS='-O0 -g' USE_LTO=0 OPT_LEVEL=0 NATIVE=0 \
make bench_random_mixed_hakmem -j4
ENV
HAKMEM_BENCH_MIN_SIZE=16
HAKMEM_BENCH_MAX_SIZE=1024
HAKMEM_TINY_HEAP_PROFILE=C7_SAFE
HAKMEM_TINY_C7_HOT=1
HAKMEM_TINY_HOTHEAP_V2=0
HAKMEM_SMALL_HEAP_V3_ENABLED=1
HAKMEM_SMALL_HEAP_V3_CLASSES=0x80
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_TINY_FRONT_V3_ENABLED=1
HAKMEM_TINY_FRONT_V3_LUT_ENABLED=1
HAKMEM_TINY_PTR_FAST_CLASSIFY_ENABLED=1
perf 例
perf record -F 5000 --call-graph dwarf -e cycles:u \
-o perf.data.tiny_front_tf3 \
./bench_random_mixed_hakmem 1000000 400 1
- perf 計測時はログを極力 OFF、ENV は MIXED_TINYV3_C7_SAFE をベースにする。
Research Profile 3: C5_C6_SMALL_HEAP_V7_LEARNER(SmallObject v7 C5/C6 専用プリセット, Phase v10)
目的
- C5/C6 サイズ帯専用(Mixed 本線では使わない)
- SmallObject v7 + Learner で動的ルート最適化を検証。
- Learner がワークロード比率を監視し、C5 route を v7 ↔ MID_v3 で自動切り替え。
- Phase v10 で v7 を「C5/C6 専用プリセット」として凍結し、本プリセットで完全に管理。
性能実績
- C5/C6 mixed (200-500B, 300K iter):
- v7 + Learner: 38.7M ops/s (+127% vs Legacy)
- Learner route switch: C5 ratio 28% < threshold 30% → MID_v3 自動切り替え
ENV(v7 C5/C6 opt-in)
HAKMEM_BENCH_MIN_SIZE=200
HAKMEM_BENCH_MAX_SIZE=500
HAKMEM_SMALL_HEAP_V7_ENABLED=1 # ★ v7 ON
HAKMEM_SMALL_HEAP_V7_CLASSES=0x60 # ★ C5(0x20) + C6(0x40)
# Learner は v7 enabled 時にデフォルト ON (Phase v10)
# HAKMEM_SMALL_LEARNER_V7_ENABLED=0 で個別無効化可
テストコマンド
# C5/C6 混合(50/50)
HAKMEM_BENCH_MIN_SIZE=200 HAKMEM_BENCH_MAX_SIZE=500 \
HAKMEM_SMALL_HEAP_V7_ENABLED=1 HAKMEM_SMALL_HEAP_V7_CLASSES=0x60 \
./bench_random_mixed_hakmem 300000 400 1
# C6 heavy(90% C6, 10% C5)→ Learner route switch トリガー
HAKMEM_BENCH_MIN_SIZE=200 HAKMEM_BENCH_MAX_SIZE=500 \
HAKMEM_SMALL_HEAP_V7_ENABLED=1 HAKMEM_SMALL_HEAP_V7_CLASSES=0x60 \
./bench_allocators --allocator hakmem --scenario c6heavy --iterations 10
期待値
- Throughput: 38-39M ops/s (C5/C6 mixed)
- Learner log:
[LEARNER_V7] C5 route switch: V7 → MID_V3(C5 ratio < 30%) - Route decision:
[POLICY_V7_INIT] C5: v7, C6: v7
注意
- Mixed 本線(16-1040B)では v7 OFF (HAKMEM_SMALL_HEAP_V7_ENABLED=0)
- v7 は C5/C6 専用、他のサイズ帯には影響なし
- Learner は C5 の動的最適化のみ(C6 は固定 v7)
- Phase v10 で v3/v4/v5 削除済み(古い ENV は無視される)
Research Profile 4: C6_ULTRA_INTRUSIVE_EXPERIMENT_V12(C6 ULTRA intrusive LIFO vs array magazine, Phase TLS-UNIFY-3)
FROZEN - Research Only: Phase TLS-UNIFY-3 validation complete. Findings:
- C6-heavy (257-512B): +3.8% improvement ✅
- Mixed (16-1024B): -12~14% regression ❌ (policy overhead + TLS contention)
- Recommendation: Use only for C6-heavy workloads or research/debugging
- Default: OFF (MID v3/v3.5 faster for Mixed)
目的
- Phase TLS-UNIFY-3 validation: C6 ULTRA intrusive LIFO freelist と array magazine の比較。
- C6 を ULTRA path に routing し、TLS 内の LIFO 表現だけを A/B。
- ULTRA routing は MID v3/v3.5 を override するため、研究コンテキストのみで使用。
性能実績
- C6-heavy (257-512B, 1M iter, ws=200, 5-run mean):
- Baseline (C6=MID v3.5): 55.3M ops/s
- ULTRA+array (intrusive OFF): 57.4M ops/s (+3.79% vs Baseline)
- ULTRA+intrusive (intrusive ON): 54.5M ops/s (-1.44% vs Baseline, ✅ PASS)
- IFL stats: push=265,890 / pop=265,815 / fallback=0(perfect LIFO behavior)
- Mixed 16–1024B(標準本線):
- ULTRA+intrusive は約 -14% の回帰を確認。
- Root cause:
- 8 クラス(C0–C7)が 1TLS 内で競合し、C4/C5/C6/C7 の ULTRA TLS(約2KB)が奪い合い状態になる。
- ULTRA miss が増え、Legacy fallback が約 24% に達する。
- 結論: Mixed 本線では C6 ULTRA を使わない(
MIXED_TINYV3_C7_SAFEの設計どおり)。
ENV(ULTRA intrusive opt-in)
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=512
HAKMEM_TINY_C6_ULTRA_FREE_ENABLED=1 # ★ C6 を ULTRA path に routing
HAKMEM_TINY_C6_ULTRA_INTRUSIVE_FL=1 # ★ intrusive LIFO freelist 有効化
HAKMEM_FREE_PATH_STATS=1 # stats 取得用
テストコマンド
# Baseline: C6=MID v3.5 (ULTRA routing なし)
HAKMEM_BENCH_MIN_SIZE=257 HAKMEM_BENCH_MAX_SIZE=512 \
./bench_random_mixed_hakmem 1000000 200 1
# ULTRA+array: array magazine (intrusive OFF)
HAKMEM_BENCH_MIN_SIZE=257 HAKMEM_BENCH_MAX_SIZE=512 \
HAKMEM_TINY_C6_ULTRA_FREE_ENABLED=1 HAKMEM_TINY_C6_ULTRA_INTRUSIVE_FL=0 \
HAKMEM_FREE_PATH_STATS=1 ./bench_random_mixed_hakmem 1000000 200 1
# ULTRA+intrusive: intrusive LIFO freelist
HAKMEM_BENCH_MIN_SIZE=257 HAKMEM_BENCH_MAX_SIZE=512 \
HAKMEM_TINY_C6_ULTRA_FREE_ENABLED=1 HAKMEM_TINY_C6_ULTRA_INTRUSIVE_FL=1 \
HAKMEM_FREE_PATH_STATS=1 ./bench_random_mixed_hakmem 1000000 200 1
期待値
- ULTRA+intrusive >= Baseline(or small regression < 5%)
- c6_ifl_fallback ≈ 0(intrusive LIFO が正常動作)
- c6_ultra_free/alloc > 0(ULTRA path が動作)
注意
- WARNING: ULTRA routing overrides MID v3/v3.5 - use only in research context.
- Usage: C6-heavy 専用の研究箱として使用(Mixed 本線では非推奨 / 回帰あり)。
- 本線には載せない、研究箱扱い。
共通注意
- プリセットから外れて単発の ENV を積み足すと再現が難しくなるので、まずは上記いずれかからスタートし、変更点を必ずメモしてください。
- v2 系(Pool v2 / Tiny v2)はベンチごとに opt-in。不要なら常に 0。
- Phase v10: v3/v4/v5 は削除されました(古い ENV は無視されます)。C5/C6 最適化には本プリセット(v7+Learner)を使用してください。