Files
hakmem/docs/analysis/TINY_HEAP_BOX_DESIGN.md
Moe Charm (CI) 8f18963ad5 Phase 36-37: TinyHotHeap v2 HotBox redesign and C7 current_page policy fixes
- Redefine TinyHotHeap v2 as per-thread Hot Box with clear boundaries
- Add comprehensive OS statistics tracking for SS allocations
- Implement route-based free handling for TinyHeap v2
- Add C6/C7 debugging and statistics improvements
- Update documentation with implementation guidelines and analysis
- Add new box headers for stats, routing, and front-end management
2025-12-08 21:30:21 +09:00

233 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

TinyHeapBox Design (C7 先行載せ替え)
====================================
概要
----
- 目的: Unified Cache を経由せず、mimalloc 風の TinyHeap (page 内 freelist + current/partial/full) を 1 箱に閉じ込める。
- Box 境界: Superslab / Warm / Tier / Guard との接続は
- alloc 側: `tiny_heap_alloc_slow_from_class()` (ページ枯渇時だけ)
- free 側: `tiny_heap_page_becomes_empty()` (全 free になった瞬間だけ)
の 1 箇所に集約し、ホットパスは TinyHeap 内で完結させる。
- A/B: `HAKMEM_TINY_HEAP_BOX=0` → 従来 Unified front、`=1` → TinyHeap front (いまは C7 のみ)。
TinyHeap Profile (ENV ショートカット)
--------------------------------------
- `HAKMEM_TINY_HEAP_PROFILE` を新設し、プロファイルで TinyHeap のデフォルト構成を切り替え可能にしたENV が未指定のときのデフォルトを決める箱)。
- LEGACY (デフォルト): TinyHeap OFFclass mask=0x00, meta_mode=0
- C7_SAFE: TinyHeap ON, class mask=0x80 (C7 のみ), C7 meta_mode=1SAFE`HAKMEM_TINY_HEAP_BOX` も自動 ON。C7_HOT は別途 1 にする。
- C7_ULTRA_BENCH: class mask=0x80, meta_mode=2ULTRA, bench専用`HAKMEM_TINY_HEAP_BOX` も ON。
- CUSTOM: `HAKMEM_TINY_HEAP_CLASSES` / `HAKMEM_TINY_C7_META_MODE` を直接指定する従来挙動。
- 優先順位:
1. `HAKMEM_TINY_HEAP_BOX=0` なら TinyHeap 無効。
2. `HAKMEM_TINY_HEAP_CLASSES` があればそのビットマスクを最優先。
3. 無ければ `HAKMEM_TINY_HEAP_PROFILE` からデフォルト mask/meta_mode を決める。
4. `HAKMEM_TINY_C7_META_MODE` があれば C7 meta_mode はそれを優先(無ければ profile→旧 `HAKMEM_TINY_C7_META_LIGHT` の順)。
- 推奨フラグ例:
- C7-only 比較: `HAKMEM_BENCH_C7_ONLY=1 HAKMEM_TINY_HEAP_PROFILE=C7_SAFE HAKMEM_TINY_C7_HOT=1 HAKMEM_TINY_LARSON_FIX=1`
- Mixed 161024B: `HAKMEM_BENCH_MIN_SIZE=16 HAKMEM_BENCH_MAX_SIZE=1024 HAKMEM_TINY_HEAP_PROFILE=C7_SAFE HAKMEM_TINY_C7_HOT=1`C6 TinyHeap はデフォルト OFF のまま)
標準プロファイル (v1 締め)
--------------------------
- 推奨候補:
- LEGACY … TinyHeap 全無効(基準)。
- C7_SAFE … class mask=0x80, meta_mode=1SAFEに加え `HAKMEM_TINY_STATS_BOX=1 HAKMEM_TINY_STATS_BATCH=0` をセットするのが標準。C6 は OFF。
- bench/実験専用:
- C7_ULTRA_BENCHmeta_mode=2、C6 TinyHeap マスク (0x40/0xC0)、`HAKMEM_TINY_STATS_BATCH=1`
- デフォルト運用: PROFILE=LEGACY か PROFILE=C7_SAFE を手で選択し、C6 は明示しない限り OFF。詳細の次ステップ案は `docs/analysis/TINY_NEXT_STEPS.md` に記載。
- Phase 20 追加: C6 Hot front を C7 と対称に導入ENV `HAKMEM_TINY_C6_HOT=1` + class mask で有効化。Front を薄くしても C6 TinyHeap は依然回帰が大きい。C6 は v1 では bench/実験用の位置づけに凍結。
主要構造 (core/box/tiny_heap_box.h)
-----------------------------------
- `tiny_heap_page_t`: ページ内 freelist/used/capacity と Superslab メタ (ss/meta/slab_idx/base) を保持。
- `tiny_heap_class_t`: class ごとの current_page / partial_pages / full_pages と固定ノード配列 (`TINY_HEAP_MAX_PAGES_PER_CLASS` デフォルト4) に加え、stride をキャッシュ。
- `tiny_heap_ctx_t`: TLS の TinyHeap コンテキスト。全クラス分の `tiny_heap_class_t` を持ち、初回だけ memset で初期化。
- API (static inline):
- `tiny_heap_ctx_for_thread()` / `tiny_heap_class()` アクセサ
- `tiny_heap_attach_page(ctx, cls, ss, slab_idx)` / `tiny_heap_page_of(ctx, cls, base)` (TLS fast-first → fallback lookup)
- `tiny_heap_alloc_class_fast()` / `tiny_heap_alloc_slow_from_class()` ホット/スロー境界
- `tiny_heap_free_class_fast_with_meta()` / `tiny_heap_free_class_fast()` free ホットパス
- ポリシー:
- freelist pop で meta->used / ss_active_add をインクリメント。carve は `meta->carved++` を併走させ、Unified/旧経路との整合を維持。
- free で meta->used / ss_active_dec_one をデクリメント。empty になったら `ss_partial_publish()` のヒントだけ出してノードを解放。
C7HotBox への適用 (core/box/tiny_c7_hotbox.h)
---------------------------------------------
- `tiny_c7_*` 型は TinyHeapBox の型 alias。C7 固有 API は薄いラッパのみ:
- `tiny_c7_alloc_fast(size)``tiny_heap_alloc_class_fast(ctx, 7, size)`
- `tiny_c7_free_fast_with_meta(ss, slab_idx, base)``tiny_heap_free_class_fast_with_meta(ctx, 7, ...)`
- `tiny_c7_page_of(base)``tiny_heap_page_of(ctx, 7, base)`
- ENV: `HAKMEM_TINY_HEAP_BOX=1` かつ `HAKMEM_TINY_C7_HOT=1` のときだけ Gate で class7 を TinyHeap 経路に切り替え。
- 既存の C7 専用 TLS 状態 (`g_tiny_c7_hot_heap`) は廃止し、共通 `g_tiny_heap_ctx` に統合。
Front Gate (core/front/malloc_tiny_fast.h)
------------------------------------------
- alloc: class_idx==7 & size==1024 かつ TinyHeapBox ON で `tiny_c7_alloc_fast()` に直行。それ以外は Unified Cache front。
- free : Larson owner 判定に関係なく、TinyHeapBox ON + class7 なら meta 渡し free (`tiny_c7_free_fast_with_meta`) を優先。ss_fast_lookup 失敗時は `tiny_c7_free_fast()` で安全側。
- Phase16: Route Snapshot Box (`tiny_route_env_box.h`) を追加し、起動時に `g_tiny_route_class[cls]` に TinyHeap/Legacy を確定。`malloc_tiny_fast` / `free_tiny_fast` は「size→class→route LUT→heap or legacy」の 1 分岐構造に整理。`HAKMEM_TINY_FRONT_CLASS_STATS(_DUMP)=1` で front クラス分布も取得可能。
C7 は TLS SLL を使わないTinyHeap front ON 時)
-----------------------------------------------
- ENV 結合: `tiny_c7_heap_mode_enabled()` = `HAKMEM_TINY_HEAP_BOX=1` かつ `HAKMEM_TINY_C7_HOT=1`
- Refill/prewarm: `sll_refill_small_from_ss()` / `sll_refill_batch_from_ss()` は C7 を即 return。`hak_tiny_prewarm_tls_cache()` も C7 prewarm を skip。
- Push ガード: `tls_sll_push_impl()` で class7+TinyHeap front を拒否False return
- Slow path バイパス: `hak_tiny_alloc_slow()` で同条件なら TinyHeapBox (`tiny_c7_alloc_fast`) に委譲し、旧 slow 経路を通さない。
- ベンチ: `HAKMEM_BENCH_C7_ONLY=1` 20k ループ / `HAKMEM_TINY_SLL_LOG_ANY=1` でも C7 の TLS SLL ログは 0、`HAKMEM_TINY_HEAP_BOX=1` で SEGV なく完走 (≈4246M ops/s)。レガシー (`HEAP_BOX=0`) も ≈41.8M ops/s で回帰なし。
Phase 2: 可視化と警告抑止
-------------------------
- `HAKMEM_TINY_C7_HEAP_STATS` で C7 TinyHeap のステップ別カウンタを取得alloc_fast_current / alloc_slow_prepare / free_fast_local / free_slow_fallback / alloc_prepare_fail / alloc_fail`HAKMEM_TINY_C7_HEAP_STATS_DUMP=1` で終了時に stderr ダンプ。
- meta-light フラグ `HAKMEM_TINY_C7_META_LIGHT` を追加Phase 3 でベンチ用実装を追加。ON のときは meta->used / ss_active_* の per-alloc 更新をスキップし、page->used のみで管理するベンチ専用モード。
- Tiny lane failed 警告は TinyHeap front ON の C7 では出さないように `hak_alloc_at` で C7 を TinyHeapBox 扱いに統一。
- 参考値C7-only 20k, stats ON: alloc_fast_current=10052 / alloc_slow_prepare=7681 / free_fast_local=10053 / free_slow_fallback=0 / alloc_prepare_fail=0 / alloc_fail=0。
Phase 3: stride キャッシュ + meta-lightbench
-----------------------------------------------
- ctx 初期化時に全クラスの stride を前計算し、`tiny_heap_page_pop()` などで hcls->stride を直接利用。
- free 側で class7 は「free した page を current_page に優先」するように変更し、alloc_slow_prepare の頻度を低減。
- `HAKMEM_TINY_C7_META_LIGHT=1` で meta->used / ss_active_* を per-alloc 更新しない実験モードを実装(デフォルト OFF、Superslab/Tier stats は本番向けでは正しく減算されないため bench 用)。
- ベンチC7-only 20k/ws=64, Release):
- legacy (HEAP_BOX=0 HOT=1): ≈42.5M ops/s
- TinyHeap front (HEAP_BOX=1 HOT=1 LARSON_FIX=1, META_LIGHT=0): ≈43.2M ops/s、stats=alloc_fast_current=10052 / alloc_slow_prepare=7681 / free_fast_local=10053
- TinyHeap front + meta-light (META_LIGHT=1): ≈48.1M ops/s、stats=alloc_fast_current=5837 / alloc_slow_prepare=5179 / free_fast_local=8727
Phase 4: meta-light をページ境界バッチ flush 化bench 用)
-------------------------------------------------------
- `tiny_heap_page_t` に C7 用 delta (`c7_used_delta` / `c7_active_delta`) を追加し、meta-light ON では per-alloc で delta のみ更新。
- `tiny_c7_meta_flush_page()` を導入し、ページが空になる/ノード解放時に delta をまとめて meta->used / total_active_blocks に反映(負 delta は `ss_active_dec_one` ループで処理する素朴版)。
- Box 境界は従来通り `tiny_heap_alloc_slow_from_class()``tiny_heap_page_becomes_empty()` に集約。meta-light は bench/研究用でデフォルト OFF。
- ベンチC7-only 20k/ws=64, Release):
- META_LIGHT=0: ≈41.9M ops/salloc_fast_current=10052 / alloc_slow_prepare=7681 / free_fast_local=10053
- META_LIGHT=1バッチ flush: ≈53.5M ops/salloc_fast_current=11013 / alloc_slow_prepare=3 / free_fast_local=9294
Phase 5: delta debug フック + 長時間ラン確認
-------------------------------------------
- `HAKMEM_TINY_C7_DELTA_DEBUG` を追加し、meta-light ON 時に `tiny_c7_heap_debug_dump_deltas()` で class7 ノードの `c7_used_delta` / `c7_active_delta` をダンプ可能にした。per-TU static だが ENV ゲート付き。
- `core/hakmem_tiny.c` の destructor からも同 helper を呼び、`HAKMEM_TINY_C7_META_LIGHT=1 HAKMEM_TINY_C7_DELTA_DEBUG=1` でベンチ終了時に自動チェック。
- 長時間 C7-only (ws=64, Release) の例:
- 100k: META_LIGHT=1+DELTA_DEBUG ≈51.3M ops/s、delta 残 = idx0 used_delta=7669 active_delta=7669 used=6。
- 200k: META_LIGHT=1+DELTA_DEBUG ≈48.1M ops/s、delta 残 = idx0 used_delta=14727 active_delta=14727 used=6。
- delta が live page に積み上がるempty/release でのみ flush する設計のため)ことが確認できた。今後は閾値 flush や partial→current の調整で長時間ランでも delta を抑える方針。
Phase 6: delta 閾値 flush + attach 時 clampbench
---------------------------------------------------
- `tiny_c7_delta_should_flush()` を追加し、C7 meta-light ON 時に `|delta| >= max(256, capacity*16)``tiny_c7_meta_flush_page()` をホットパスから呼ぶ。per-alloc atomic なしで delta を capacity の数倍以内に抑える。
- `tiny_heap_attach_page()` で C7 meta-light が有効なら `used``capacity` に clamp し、過去ラン由来の meta->used が異常に大きくても current/partial を復帰できるようにした(同時に c7_*_delta を 0 にリセット)。
- 長時間 C7-only (ws=64, Release, DELTA_DEBUG=1):
- 100k: delta summary = nonzero_pages=0 used_delta_sum=0 active_delta_sum=0
- 200k: 同上delta=0
- ベンチ (C7-only 20k/ws=64, Release):
- Legacy HEAP_BOX=0 HOT=1: ≈42.5M ops/s
- TinyHeap HEAP_BOX=1 HOT=1 LARSON_FIX=1 META_LIGHT=0: ≈43.1M ops/s
- TinyHeap META_LIGHT=1 (閾値 flush/clamp): ≈42.6M ops/s、delta debug なしでも off と同等レンジに戻った。
Phase 7: クラス選択式 TinyHeapC6 拡張の足場)
------------------------------------------------
- ENV `HAKMEM_TINY_HEAP_CLASSES` を追加bitmask, デフォルト 0x80=C7 のみ)。`tiny_heap_class_route_enabled(cls)` で TinyHeap front を使うクラスを判定し、C6/C5 を段階的に載せ替える A/B を可能にした。
- Front gate: `malloc_tiny_fast` / `free_tiny_fast` がクラスごとに TinyHeap 経路を選択。C7 は従来通り `tiny_c7_heap_mode_enabled()``HAKMEM_TINY_C7_HOT` 連動でガードし、C6 などは `tiny_heap_alloc/free_class_fast()` に直行。
- TLS SLL との切り離しをクラス単位に拡張: `sll_refill_small_from_ss` / `sll_refill_batch_from_ss` / `hak_tiny_prewarm_tls_cache``tiny_heap_class_route_enabled(cls)` なら即 return/skip。TinyHeap クラスは Superslab↔TinyHeapBox のみを通る。
- 例: `HAKMEM_TINY_HEAP_CLASSES=0x40` で C6 だけ TinyHeap、`0xC0` で C6+C7 TinyHeap。今後のベンチで C6-only / mixed ワークロードの hit 率と slow_prepare 割合を確認する。
Phase 8: C6 TinyHeap A/B と経路確認
-----------------------------------
- ルートC6 を TinyHeap に載せた場合)
- alloc: `malloc_tiny_fast → class_idx=6 → tiny_heap_class_route_enabled(6)=1 → tiny_heap_alloc_class_fast(ctx,6,size)` → current/partial を使い、枯渇時のみ Superslab/Tier/Guard に降りる。
- free : `free_tiny_fast → header→class_idx=6 → tiny_heap_class_route_enabled(6)=1 → tiny_heap_free_class_fast(ctx,6,ptr)` → page 内 free_list で完結し、empty 時だけ slow 境界へ。
- SLL/Prewarm 切り離し: `sll_refill_small_from_ss` / `sll_refill_batch_from_ss` / `hak_tiny_prewarm_tls_cache``tiny_heap_class_route_enabled(cls)` で C6 も early return/skip するため、TinyHeap クラスは TLS SLL を一切踏まない。
- ベンチ (Release, iters=20k, ws=256, min=257 max=768)
- TinyHeap OFF (`HEAP_BOX=0`): ≈45.7M ops/s。
- C6 だけ TinyHeap (`HEAP_BOX=1` `HEAP_CLASSES=0x40` `C7_HOT=0`): ≈39.7M ops/s。
- C6+C7 TinyHeap (`HEAP_BOX=1` `HEAP_CLASSES=0xC0` `C7_HOT=1`): ≈34.1M ops/s、Tiny lane failed 警告が発生(要調査)。
- Mixed 161024B (iters=20k, ws=256)
- TinyHeap OFF: ≈46.8M ops/s。
- C7 のみ TinyHeap (`HEAP_CLASSES=0x80`): ≈39.4M ops/sTiny lane failed 警告あり)。
- C6+C7 TinyHeap (`HEAP_CLASSES=0xC0`): ≈33.8M ops/sTiny lane failed 警告あり)。
- メモ: C6/C7 を TinyHeap に載せた際に Tiny lane failed 警告が出るケースがある。現状は A/B 計測を優先し、次フェーズで lane 判定の整合・TinyHeap fallback の整理が必要。
Phase 9: Tiny lane 判定の整理TinyHeap を「成功」とみなす)
--------------------------------------------------------
- 問題: C6/C7 を TinyHeap に載せた mixed ワークロードで `Tiny lane failed` 警告が出ていたGate 目線で Tiny が失敗扱いになっていた。TLS SLL は踏んでいないので、TinyHeap 成功を Tiny lane 成功として扱うのが正しい。
- 変更 (core/box/hak_alloc_api.inc.h):
- `hak_alloc_at` に Tiny route 状態を保持するフラグclass_idx / TinyHeap route on/offを追加。
- Tiny front が NULL でも、TinyHeap route が有効なクラスは TinyHeap を直接試し、成功したら Tiny lane 成功として即 return。
- Tiny lane 失敗ログは「TinyHeap route off かつ tiny_tried」時のみ出す。TinyHeap route の NULL はベンチ用フォールバック扱いで静かに ENOMEM を返す。
- 結果 (警告抑止後、Release, iters=20k, ws=256):
- C6 偏重 (min=257 max=768): OFF≈47.8M / C6のみ TinyHeap≈39.2M / C6+C7≈31.3M(警告なし)。
- Mixed 161024B: OFF≈47.6M / C7のみ TinyHeap≈36.9M / C6+C7≈30.3M(警告なし)。
- 今後: TinyHeap route の性能はまだ OFF より下がるケースがあるため、slow_prepare/hit 率の改善や C6 向け最適化を別フェーズで実施する。
Phase ULTRA: C7 meta モードの三段化bench 専用 ULTRA 追加)
------------------------------------------------------------
- ENV `HAKMEM_TINY_C7_META_MODE` を追加0:OFF, 1:SAFE meta-light=従来の delta+閾値 flush/clamp, 2:ULTRA。従来の `HAKMEM_TINY_C7_META_LIGHT` は mode 未指定時の後方互換ゲートとして残し、mode を指定しない場合は SAFE=1 相当。
- ULTRA (mode=2) は C7-only ベンチ専用。per-alloc で meta->used / ss_active_* を一切更新せず、delta/flush もスキップする。2024-xx-xx 時点で pop/push の meta->freelist/carved atomic も省略してオーバーヘッドを削減Box 境界は維持するが Superslab/Tier の統計整合性は保証しない)。
- SAFE (mode=1) はこれまでのページ境界 flush + 閾値 flush + attach clamp を維持し、本番で使うならこちら。
- ベンチ (C7-only 20k/ws=64, Release, HEAP_BOX=1, HEAP_CLASSES=0x80, HOT=1, LARSON_FIX=1):
- mode=0 (meta-light OFF): ≈38.7M ops/salloc_fast_current=10052 / alloc_slow_prepare=7681
- mode=1 (SAFE): ≈34.1M ops/salloc_fast_current=5837 / alloc_slow_prepare=5179
- mode=2 (ULTRA, bench): ≈41.6M ops/salloc_fast_current=5948 / alloc_slow_prepare=5068
- C7 current_page 固定化ULTRA 専用):
- ULTRA で tiny_heap_page_becomes_empty / mark_full の unlink を避け、free で常に current_page に据え置くように調整。
- prepare は current_page が生きていれば即 return する軽量パスに変更し、C7-only 20k/ws=64 (mode=2) で ops≈52.0M / alloc_fast_current=11015 / alloc_slow_prepare=1 / prepare_calls=1 まで改善。
- SAFE への逆輸入可否は別途検討ULTRA は bench 限定、本番は OFF/SAFE を推奨)。
- C7 current_page 可視化: `g_c7_page_stats`prepare_calls / prepare_with_current_null / prepare_from_partial / current_set_from_free / current_dropped_to_partial`HAKMEM_TINY_C7_HEAP_STATS=1` で出力。現状 C7-only ULTRA では `prepare_with_current_null=prepare_calls` で free 側が current を保持できていないことが判明(要ポリシー見直し)。
- 本番ドキュメントでは ULTRA を必ず OFFmode=0/1にすること。ULTRA で得た知見は安全側に逆輸入する前提。
Phase 12: SAFE (mode=1) への current_page 逆輸入
-------------------------------------------------
- SAFE でも C7 current_page を極力保持するように変更:
- free: used>0 かつ free_list がある page は current に据え直し、empty でも delta を flush したうえで detach/publish せず current を保持meta/active 整合性は維持)。
- mark_full: C7 meta_light が current を指す場合は unlink せず据え置き。
- prepare_page: C7 meta_light で current に空きがあれば即 returnrefill へ降りない)。
- ベンチ (C7-only, ws=64, HEAP_BOX=1, HEAP_CLASSES=0x80, HOT=1, LARSON_FIX=1):
- SAFE mode=1 (meta-light) 20k: ≈46.6M ops/s、alloc_fast_current=11015 / alloc_slow_prepare=1 / free_fast_local=8726、C7_PAGE_STATS: prepare_calls=1。
- SAFE 長時間: 100k≈46.7M、200k≈44.99M。`HAKMEM_TINY_C7_DELTA_DEBUG=1` でも `[C7_DELTA_SUMMARY] nonzero_pages=0 used_delta_sum=0 active_delta_sum=0` を確認。
- ULTRA(mode=2) は bench 専用のまま。SAFE は meta/active の整合性を保ちつつ slow_prepare をほぼゼロに抑える構成になった。
今後の拡張ステップ
------------------
- C5〜C6 を TinyHeapBox に移す際は `tiny_heap_alloc_class_fast()` を流用し、Box 境界 (ページ補給/返却) の 1 箇所化を維持する。
- `TINY_HEAP_MAX_PAGES_PER_CLASS` の調整と stats/Tier 更新の扱いは次フェーズで検証。
- TLS SLL は今後 C0〜C6 のための箱として維持し、C7 は TinyHeapBox↔Superslab/Tier/Guard の二層構造に限定する。
Phase 13: クラス汎用 TinyHeap stats + C6/C7 混在ベンチ
----------------------------------------------------
- Stats をクラス配列 `TinyHeapClassStats g_tiny_heap_stats[TINY_NUM_CLASSES]` に拡張。ENV は `HAKMEM_TINY_HEAP_STATS` / `_DUMP`(従来の `_C7_` も互換。fast/slow/fallback/prepare_fail/fail をクラスごとに記録できる。
- Mixed 161024B (iters=20k, ws=256, LARSON_FIX=1):
- TinyHeap OFF: ≈43.7M ops/s。
- C7 SAFE のみ TinyHeap (`HEAP_BOX=1 HEAP_CLASSES=0x80 META_MODE=1 HOT=1`): ≈44.9M ops/s、`HEAP_STATS[7] fast=5691 slow_prepare=1`
- C6+C7 TinyHeap (`HEAP_CLASSES=0xC0` 同条件): ≈39.3M ops/s、`HEAP_STATS[6] fast=2744 slow=1`, `HEAP_STATS[7] fast=5691 slow=1`
- C6 偏重 (min=257 max=768, iters=20k, ws=256):
- TinyHeap OFF: ≈43.8M ops/s。
- C6 TinyHeap のみ (`HEAP_CLASSES=0x40`, C7 legacy): ≈38.5M ops/s、`HEAP_STATS[6] fast=5372 slow=1`
- C6+C7 TinyHeap (`HEAP_CLASSES=0xC0`, C7 SAFE): ≈40.6M ops/s、`HEAP_STATS[6] fast=5372 slow=1`, `HEAP_STATS[7] fast=5691 slow=1`
- 示唆:
- C7 SAFE は mixed でも悪化せず、C7-only では legacy 超え → デフォルトで TinyHeap に載せる候補。
- C6 は slow_prepare はほぼ 0 でも経路オーバーヘッドで throughput が落ちるため、当面は bench/実験用 (HEAP_CLASSES=0x40/0xC0) に留める。C6 を本格移行するなら current_page ポリシーや meta-light 相当の最適化が必要。
- 推奨例: 本番寄せ C7 = `HEAP_BOX=1 HEAP_CLASSES=0x80 META_MODE=1`、C7-only bench = `META_MODE=2`ULTRA, bench 専用。C6 TinyHeap はデフォルト OFF のまま。
Phase 18: C6 SAFE 再計測とメタモード足場(挙動は安全寄せのまま)
----------------------------------------------------------------
- ENV `HAKMEM_TINY_C6_META_MODE` を追加0/1。現状は整合優先のため behavior mode=0 扱いC6 は meta/active を per-alloc 更新、delta/flush は未使用。C6 を TinyHeap に載せるときは `HAKMEM_TINY_HEAP_BOX=1 HAKMEM_TINY_HEAP_CLASSES=0x40/0xC0` を明示。
- ベンチ (Release, iters=20k, ws=256, LARSON_FIX=1):
- C6 偏重 (257768B):
- LEGACY (TinyHeap OFF): ≈44.28M ops/s。
- C6 TinyHeap mask=0x40, META_MODE=0: ≈38.81M ops/scls6 fast=5372 / slow_prepare=1
- C6 TinyHeap mask=0x40, META_MODE=1: ≈38.59M ops/s同じく slow_prepare≒1
- C6+C7 TinyHeap mask=0xC0, C6 META=1 / C7 META=1: ≈39.94M ops/scls6 fast=5372/slow=1, cls7 fast=5691/slow=1
- Mixed 161024B:
- LEGACY: ≈44.27M ops/s。
- PROFILE=C7_SAFE (mask=0x80, C7 META=1): ≈43.64M ops/s。
- C6 TinyHeap mask=0x40, META_MODE=0: ≈38.48M ops/scls6 fast=2744/slow=1
- C6 TinyHeap mask=0x40, META_MODE=1: ≈38.66M ops/scls6 fast=2744/slow=1
- C6+C7 TinyHeap mask=0xC0, C6 META=1 / C7 META=1: ≈39.49M ops/scls6 fast=2744/slow=1, cls7 fast=5691/slow=1
- メモ: C6 は slow_prepare がほぼゼロでも回帰しているため、次は meta-light の安全な適用か Gate/Route 側の命令削減を検討。現状の C6 SAFE は「挙動は mode 0 相当(安全重視)」で、ベンチ比較用のスイッチとして位置付け。
Phase 17: C7 フロント超直線化Gate→Heap を 1 本に)
---------------------------------------------------
- Route Snapshot ベースのヘルパ `tiny_c7_front_uses_heap()` を追加し、class7 が TinyHeap route かどうかを 1 LUT で判定。
- `malloc_tiny_fast` 冒頭に C7 専用パスを追加: `size==1024 && tiny_c7_front_uses_heap()` のとき class/LUT/route を飛ばして `tiny_c7_alloc_fast` へ直行、miss 時だけ `tiny_cold_refill_and_alloc(7)` に静かにフォールバック。他クラスは従来の route LUT 経由を維持。
- `free_tiny_fast` も class7 が Heap route のときに先に判定し、Larson owner 一致後は `tiny_c7_free_fast_with_meta` へ直行route はスナップショットから 1 回だけ読む。C7 以外は既存の Larson/SLL/UC 経路を継続。
- ベンチ (Release, iters=20k, LARSON_FIX=1):
- C7-only ws=64: PROFILE=LEGACY ≈37.1M / C7_SAFE ≈38.2M / C7_ULTRA_BENCH ≈45.3M ops/s。
- Mixed 161024B ws=256: PROFILE=LEGACY ≈40.3M / C7_SAFE ≈40.7M ops/s回帰を ~-1M まで圧縮)。
- 次の選択肢メモ: (A) C6 TinyHeap を C7 SAFE 流current 固定meta-light SAFEに寄せて再評価するか、(B) Tiny front/gate/UC の命令数削減を perf で詰めるかを検討。