diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index c81cfb46..fac025af 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -11,6 +11,11 @@ - Prefault Box(`ss_prefault_box.h`)は追加済みだが、4MB MAP_POPULATE 問題を避けるためデフォルト OFF(`HAKMEM_SS_PREFAULT=0`)に設定。 ### 直近の成果 +- TinyHeap クラスマスク(C6 A/B 試験)と C6 ベンチ速報 + - ENV `HAKMEM_TINY_HEAP_CLASSES` を追加し、bitmask で TinyHeap に載せるクラスを制御(デフォルト 0x80=C7 のみ)。Gate も per-class で TinyHeap/旧フロントを切替。 + - SLL refill/prewarm は `tiny_heap_class_route_enabled(cls)` で早期 return するため、C6 を TinyHeap に載せても TLS SLL を踏まない 2 層構造を維持。 + - ベンチ (Release, iters=20k, ws=256, min=257 max=768): TinyHeap OFF ≈45.7M ops/s / C6 TinyHeap (`HEAP_CLASSES=0x40`) ≈39.7M / C6+C7 TinyHeap (`0xC0`) ≈34.1M (Tiny lane failed 警告あり)。 + - Mixed 16–1024B でも TinyHeap OFF ≈46.8M / C7 only (`0x80`) ≈39.4M / C6+C7 (`0xC0`) ≈33.8M(Tiny lane failed 警告が出る。Gate 側判定の整理が今後の課題)。 - C7 TinyHeap Phase 3(stride キャッシュ+meta-light 実装) - `tiny_heap_class_t` に stride キャッシュを追加し、ctx 初期化時に全クラスの stride を前計算。`tiny_heap_page_pop()` は hcls->stride を使うようにして C7 alloc の算術コストを削減。 - free 側で class7 は「今 free した page を current_page に優先」するように変更し、alloc_slow_prepare の頻度を下げる方向に調整。 @@ -243,6 +248,14 @@ - 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(C6 も TinyHeap に載せたら SLL を経由しない)。 - ドキュメント: TinyHeapBox/C7HotBox 設計にクラス bitmask と multi-class 対応の方針を追記。ベンチは今後 C6/C7 切替パターンで再計測予定。 +### Phase 9: Tiny lane 判定を TinyHeap と整合 +- `hak_alloc_at` で Tiny route の class_idx / TinyHeap route ON/OFF を保持し、Tiny front NULL 時に TinyHeap を直接試行。TinyHeap が有効なクラスでの NULL は静かなフォールバック扱いにし、`Tiny lane failed` 警告は legacy Tiny route が本当に失敗した場合のみ出す。 +- Gate から TinyHeap 経路で成功した alloc/free は Tiny lane 成功として扱うよう統一(C6/C7 の mixed で出ていた警告を抑止)。 +- ベンチ (Release, iters=20k, ws=256): + - C6 偏重 (min=257 max=768): OFF≈47.8M / C6-only TinyHeap≈39.2M / C6+C7 TinyHeap≈31.3M(警告なし)。 + - Mixed 16–1024B: OFF≈47.6M / C7-only TinyHeap≈36.9M / C6+C7 TinyHeap≈30.3M(警告なし)。 +- ドキュメント更新: Tiny lane 判定と TinyHeap 整合のメモを `docs/analysis/TINY_HEAP_BOX_DESIGN.md` / `docs/analysis/C7_HOTBOX_DESIGN.md` に追記。 + ホットパス perf フェーズの TODO(案) 1. tiny_alloc_fast / tiny_free_fast_v2 の再プロファイル:残存分岐・間接呼び出し・重い箱を特定。 2. Unified Cache ヒットパスを最短化:ヒット時を 1–2 load + 軽分岐に近づける(必要なら C7 専用インライン版検討)。 diff --git a/core/box/hak_alloc_api.inc.h b/core/box/hak_alloc_api.inc.h index d6a47f4b..9fd3e83d 100644 --- a/core/box/hak_alloc_api.inc.h +++ b/core/box/hak_alloc_api.inc.h @@ -6,7 +6,8 @@ #include "../hakmem_tiny.h" // For tiny_get_max_size() + hak_lane_classify.inc.h #include "../hakmem_pool.h" // Phase 2: For hak_pool_try_alloc() (Pool lane 1025B-52KB) #include "../hakmem_smallmid.h" // For Small-Mid Front Box (Phase 17-1) -#include "tiny_heap_env_box.h" // TinyHeap front gate (C7) +#include "tiny_heap_env_box.h" // TinyHeap front gate (C7 / multi-class) +#include "tiny_heap_box.h" // TinyHeapBox alloc/free helpers #include "tiny_c7_hotbox.h" // tiny_c7_alloc_fast wrapper #ifdef HAKMEM_POOL_TLS_PHASE1 @@ -70,6 +71,9 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { // Phase 16: Dynamic Tiny max size (ENV: HAKMEM_TINY_MAX_CLASS) // Default: 1023B (C0-C7), reduced to 255B (C0-C5) when Small-Mid enabled // Phase 17-1: Auto-adjusted to avoid overlap with Small-Mid + int tiny_class_idx = -1; + int tiny_heap_route = 0; + int tiny_tried = 0; if (__builtin_expect(size <= tiny_get_max_size(), 1)) { #if HAKMEM_DEBUG_TIMING HKM_TIME_START(t_tiny); @@ -86,12 +90,21 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { HKM_TIME_END(HKM_CAT_TINY_ALLOC, t_tiny); #endif // PERF_OPT: likely hint - tiny allocations usually succeed (hot path) + tiny_class_idx = hak_tiny_size_to_class(size); + tiny_heap_route = (tiny_class_idx >= 0 && tiny_heap_class_route_enabled(tiny_class_idx)); + tiny_tried = 1; + if (__builtin_expect(tiny_ptr != NULL, 1)) { hkm_ace_track_alloc(); return tiny_ptr; } - // TinyHeap front (C7) は Tiny lane の成功として扱う - if (__builtin_expect(size == 1024 && tiny_c7_heap_mode_enabled(), 0)) { - void* c7_ptr = tiny_c7_alloc_fast(size); - if (c7_ptr) { hkm_ace_track_alloc(); return c7_ptr; } + // TinyHeap route is also "Tiny lane success" (C7 or other enabled classes) + if (__builtin_expect(tiny_heap_route, 0)) { + void* th_ptr = NULL; + if (tiny_class_idx == 7 && tiny_c7_hot_enabled()) { + th_ptr = tiny_c7_alloc_fast(size); + } else { + th_ptr = tiny_heap_alloc_class_fast(tiny_heap_ctx_for_thread(), tiny_class_idx, size); + } + if (th_ptr) { hkm_ace_track_alloc(); return th_ptr; } } // PHASE 7 CRITICAL FIX: No malloc fallback for Tiny failures @@ -227,7 +240,7 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { #endif ptr = hak_os_map_boundary(size, site_id); } else { - // LANE_TINY failed - this is a design bug! + // LANE_TINY failed - treat TinyHeap route as normal fallback, legacy Tiny failure is a bug HAK_LANE_ASSERT_NO_FALLBACK(LANE_FALLBACK, size); static _Atomic int oom_count = 0; const int c7_heap_on = (size == 1024 && tiny_heap_box_enabled()); @@ -240,8 +253,15 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { return NULL; } int count = atomic_fetch_add(&oom_count, 1); - if (count < 10) { - fprintf(stderr, "[HAKMEM] BUG: Tiny lane failed for size=%zu (should not happen)\n", size); + if (tiny_heap_route) { + if (!HAKMEM_BUILD_RELEASE && count < 3) { + fprintf(stderr, "[HAKMEM] TinyHeap route fallback size=%zu class=%d (Tiny lane bypass)\n", + size, tiny_class_idx); + } + } else { + if (tiny_tried && count < 10) { + fprintf(stderr, "[HAKMEM] BUG: Tiny lane failed for size=%zu (should not happen)\n", size); + } } errno = ENOMEM; return NULL; diff --git a/docs/analysis/C7_HOTBOX_DESIGN.md b/docs/analysis/C7_HOTBOX_DESIGN.md index c931a806..938b762b 100644 --- a/docs/analysis/C7_HOTBOX_DESIGN.md +++ b/docs/analysis/C7_HOTBOX_DESIGN.md @@ -105,6 +105,20 @@ Phase 7: クラス選択式 TinyHeap(C6/C5 拡張のためのゲート) - Gate: `malloc_tiny_fast` / `free_tiny_fast` がクラスごとに TinyHeap 経路を選択。C7 は `tiny_c7_heap_mode_enabled()`(`HAKMEM_TINY_C7_HOT` 連動)を維持しつつ、他クラスは `tiny_heap_alloc/free_class_fast()` を使う薄ラッパで扱う。 - TLS SLL 側もクラス単位で分離し、`sll_refill_small_from_ss` / `sll_refill_batch_from_ss` / `hak_tiny_prewarm_tls_cache` が TinyHeap クラスを早期 return/skip。C7 は「TinyHeapBox ↔ Superslab/Tier/Guard」だけを踏む二層構造のまま。 +Phase 8: C6 を TinyHeap に載せた観測 +------------------------------------- +- TinyHeap ON + `HAKMEM_TINY_HEAP_CLASSES=0x40` で C6 を TinyHeap に載せ、SLL/prewarm/refill が early return していることを確認(C7 と同じ二層構造で動作)。 +- ベンチ (Release, iters=20k, ws=256, min=257 max=768): TinyHeap OFF ≈45.7M ops/s、C6 TinyHeap ≈39.7M ops/s、C6+C7 TinyHeap (mask=0xC0) ≈34.1M ops/s。 +- Mixed 16–1024B (iters=20k, ws=256): TinyHeap OFF ≈46.8M ops/s、C7 only TinyHeap ≈39.4M ops/s、C6+C7 TinyHeap ≈33.8M ops/s。いずれも Tiny lane failed 警告が出るケースあり(Gate 側の判定/フォールバック整理が今後の課題)。 + +Phase 9: Tiny lane 判定を TinyHeap と揃える +------------------------------------------ +- Gate (`hak_alloc_at`) が TinyHeap 経路を「Tiny lane の成功」として扱うように修正。class_idx を保持し、TinyHeap クラスなら TinyHeap 直接呼び出しも試行し、NULL の場合は静かなフォールバック(警告は legacy Tiny route のみ)。 +- 警告抑止後のベンチ (Release, iters=20k, ws=256): + - C6 偏重 (min=257 max=768): OFF≈47.8M / C6 only TinyHeap≈39.2M / C6+C7 TinyHeap≈31.3M(警告なし)。 + - Mixed 16–1024B: OFF≈47.6M / C7 only TinyHeap≈36.9M / C6+C7 TinyHeap≈30.3M(警告なし)。 +- 依然として性能は TinyHeap OFF より低いケースがあるため、C6/C7 の slow_prepare 削減や current_page 利用強化を次フェーズで行う。 + TinyHeapBox への載せ替え(Phase 1.0 構造) ------------------------------------------ - C7HotBox の実体を `core/box/tiny_heap_box.h` の汎用 TinyHeapBox 上に配置し、型は `tiny_heap_ctx_t` / `tiny_heap_page_t` へ統一。 diff --git a/docs/analysis/TINY_HEAP_BOX_DESIGN.md b/docs/analysis/TINY_HEAP_BOX_DESIGN.md index ad4e3050..f9ddb2fe 100644 --- a/docs/analysis/TINY_HEAP_BOX_DESIGN.md +++ b/docs/analysis/TINY_HEAP_BOX_DESIGN.md @@ -100,6 +100,34 @@ Phase 7: クラス選択式 TinyHeap(C6 拡張の足場) - 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 16–1024B (iters=20k, ws=256) + - TinyHeap OFF: ≈46.8M ops/s。 + - C7 のみ TinyHeap (`HEAP_CLASSES=0x80`): ≈39.4M ops/s(Tiny lane failed 警告あり)。 + - C6+C7 TinyHeap (`HEAP_CLASSES=0xC0`): ≈33.8M ops/s(Tiny 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 16–1024B: OFF≈47.6M / C7のみ TinyHeap≈36.9M / C6+C7≈30.3M(警告なし)。 +- 今後: TinyHeap route の性能はまだ OFF より下がるケースがあるため、slow_prepare/hit 率の改善や C6 向け最適化を別フェーズで実施する。 + 今後の拡張ステップ ------------------ - C5〜C6 を TinyHeapBox に移す際は `tiny_heap_alloc_class_fast()` を流用し、Box 境界 (ページ補給/返却) の 1 箇所化を維持する。 diff --git a/hakmem.d b/hakmem.d index f69ff1fa..9e85a7ce 100644 --- a/hakmem.d +++ b/hakmem.d @@ -30,19 +30,19 @@ hakmem.o: core/hakmem.c core/hakmem.h core/hakmem_build_flags.h \ core/box/ss_hot_prewarm_box.h core/box/hak_alloc_api.inc.h \ core/box/../hakmem_tiny.h core/box/../hakmem_pool.h \ core/box/../hakmem_smallmid.h core/box/tiny_heap_env_box.h \ - core/box/c7_hotpath_env_box.h core/box/tiny_c7_hotbox.h \ - core/box/tiny_heap_box.h core/box/../hakmem_tiny_superslab.h \ + core/box/c7_hotpath_env_box.h core/box/tiny_heap_box.h \ + core/box/../hakmem_tiny_superslab.h \ core/box/../superslab/superslab_inline.h core/box/../tiny_tls.h \ core/box/../hakmem_tiny_superslab.h core/box/../tiny_box_geometry.h \ - core/box/mid_large_config_box.h core/box/../hakmem_config.h \ - core/box/../hakmem_features.h core/box/hak_free_api.inc.h \ - core/hakmem_tiny_superslab.h core/box/../hakmem_trace_master.h \ - core/box/front_gate_v2.h core/box/external_guard_box.h \ - core/box/../hakmem_stats_master.h core/box/ss_slab_meta_box.h \ - core/box/../superslab/superslab_types.h core/box/slab_freelist_atomic.h \ - core/box/fg_tiny_gate_box.h core/box/tiny_free_gate_box.h \ - core/box/ptr_type_box.h core/box/ptr_conversion_box.h \ - core/box/tiny_ptr_bridge_box.h \ + core/box/tiny_c7_hotbox.h core/box/mid_large_config_box.h \ + core/box/../hakmem_config.h core/box/../hakmem_features.h \ + core/box/hak_free_api.inc.h core/hakmem_tiny_superslab.h \ + core/box/../hakmem_trace_master.h core/box/front_gate_v2.h \ + core/box/external_guard_box.h core/box/../hakmem_stats_master.h \ + core/box/ss_slab_meta_box.h core/box/../superslab/superslab_types.h \ + core/box/slab_freelist_atomic.h core/box/fg_tiny_gate_box.h \ + core/box/tiny_free_gate_box.h core/box/ptr_type_box.h \ + core/box/ptr_conversion_box.h core/box/tiny_ptr_bridge_box.h \ core/box/../hakmem_tiny_superslab_internal.h \ core/box/../hakmem_build_flags.h core/box/../box/ss_hot_cold_box.h \ core/box/../box/../superslab/superslab_types.h \ @@ -167,13 +167,13 @@ core/box/../hakmem_pool.h: core/box/../hakmem_smallmid.h: core/box/tiny_heap_env_box.h: core/box/c7_hotpath_env_box.h: -core/box/tiny_c7_hotbox.h: core/box/tiny_heap_box.h: core/box/../hakmem_tiny_superslab.h: core/box/../superslab/superslab_inline.h: core/box/../tiny_tls.h: core/box/../hakmem_tiny_superslab.h: core/box/../tiny_box_geometry.h: +core/box/tiny_c7_hotbox.h: core/box/mid_large_config_box.h: core/box/../hakmem_config.h: core/box/../hakmem_features.h: