diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 8d25c186..09cd0a78 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -1,6 +1,11 @@ # 本線タスク(現在) -## 更新メモ(2025-12-13 Phase 3 D2 Complete - NO-GO) +## 更新メモ(2025-12-13 Phase 4 D3 Complete - NEUTRAL) + +### Phase 4 D3: Alloc Gate Shape(HAKMEM_ALLOC_GATE_SHAPE) +- ✅ 実装完了(ENV gate + alloc gate 分岐形) +- Mixed A/B(10-run, iter=20M, ws=400): Mean **+0.56%**(Median -0.5%)→ **NEUTRAL** +- 判定: research box として freeze(default OFF、プリセット昇格しない) ### Phase 1 Quick Wins: FREE 昇格 + 観測税ゼロ化 - ✅ **A1(FREE 昇格)**: `MIXED_TINYV3_C7_SAFE` で `HAKMEM_FREE_TINY_FAST_HOTCOLD=1` をデフォルト化 diff --git a/core/box/tiny_alloc_gate_box.h b/core/box/tiny_alloc_gate_box.h index f1f4166f..b2c1a2af 100644 --- a/core/box/tiny_alloc_gate_box.h +++ b/core/box/tiny_alloc_gate_box.h @@ -31,6 +31,7 @@ #include "../tiny_region_id.h" // Header 読み出し #include "../front/malloc_tiny_fast.h" // 既存 Tiny Fast Path #include "tiny_route_box.h" // Tiny Front Routing Policy +#include "tiny_alloc_gate_shape_env_box.h" // Phase 4 D3: alloc gate shape (ENV) // 将来の拡張用コンテキスト: // - size : 要求サイズ @@ -144,6 +145,44 @@ static inline void* tiny_alloc_gate_fast(size_t size) return NULL; } + // Phase 4 D3: Alloc Gate Shape(MIXED 向けの分岐形) + // - tiny_route_get()(release の logging branch)を避ける + // - ROUTE_POOL_ONLY は必ず尊重(HAKMEM_TINY_PROFILE=hot/off を壊さない) + if (__builtin_expect(alloc_gate_shape_enabled(), 0)) { + if (__builtin_expect(g_tiny_route[class_idx & 7] == ROUTE_POOL_ONLY, 0)) { + return NULL; + } + void* user_ptr = malloc_tiny_fast_for_class(size, class_idx); +#if !HAKMEM_BUILD_RELEASE + // Layer 3a(alloc 側): 明らかに異常なポインタは debug ビルドで早期検出 + if (user_ptr) { + uintptr_t addr = (uintptr_t)user_ptr; + if (__builtin_expect(addr < 4096, 0)) { + fprintf(stderr, + "[TINY_ALLOC_GATE_RANGE_INVALID] size=%zu user=%p\n", + size, user_ptr); + fflush(stderr); + abort(); + } + } + + if (__builtin_expect(tiny_alloc_gate_diag_enabled(), 0) && user_ptr) { + TinyAllocGateContext ctx; + ctx.size = size; + ctx.user = HAK_USER_FROM_RAW(user_ptr); + ctx.class_idx = class_idx; + ctx.base = HAK_BASE_FROM_RAW(NULL); + ctx.bridge.ss = NULL; + ctx.bridge.meta = NULL; + ctx.bridge.slab_idx = -1; + ctx.bridge.meta_cls = 0xffu; + + (void)tiny_alloc_gate_validate(&ctx); + } +#endif + return user_ptr; + } + TinyRoutePolicy route = tiny_route_get(class_idx); // Pool-only: Tiny front は完全スキップ(Gate から見ると「Tiny では取れなかった」扱い) diff --git a/core/box/tiny_alloc_gate_shape_env_box.h b/core/box/tiny_alloc_gate_shape_env_box.h new file mode 100644 index 00000000..7329d025 --- /dev/null +++ b/core/box/tiny_alloc_gate_shape_env_box.h @@ -0,0 +1,22 @@ +// tiny_alloc_gate_shape_env_box.h - Phase 4 D3: Alloc Gate Shape(ENV gate) +// +// 役割: +// - alloc gate の分岐形最適化を ENV で戻せるようにする(default OFF) +// +// ENV: +// - HAKMEM_ALLOC_GATE_SHAPE=0/1 +// +#pragma once + +#include + +// -1: uninitialized, 0/1: cached +static int g_alloc_gate_shape_enabled = -1; + +static inline int alloc_gate_shape_enabled(void) { + if (__builtin_expect(g_alloc_gate_shape_enabled >= 0, 1)) return g_alloc_gate_shape_enabled; + + const char* e = getenv("HAKMEM_ALLOC_GATE_SHAPE"); + g_alloc_gate_shape_enabled = (e && *e && *e != '0') ? 1 : 0; + return g_alloc_gate_shape_enabled; +} diff --git a/docs/analysis/ENV_PROFILE_PRESETS.md b/docs/analysis/ENV_PROFILE_PRESETS.md index fdcc71fe..de57f898 100644 --- a/docs/analysis/ENV_PROFILE_PRESETS.md +++ b/docs/analysis/ENV_PROFILE_PRESETS.md @@ -95,6 +95,12 @@ HAKMEM_WRAP_ENV_CACHE=1 ``` - **Status**: ❌ FROZEN(Mixed **-1.44%** regression)→ default OFF, do not pursue - **Reason**: TLS overhead > benefit in Mixed workload +- **Phase 4 D3(Alloc Gate Shape)** 🔬 NEUTRAL (research only): +```sh +HAKMEM_ALLOC_GATE_SHAPE=1 +``` + - **Status**: NEUTRAL(Mixed 10-run: Mean **+0.56%** / Median **-0.5%**)→ default OFF + - **Effect**: `tiny_alloc_gate_fast()` の分岐形を簡素化(`tiny_route_get()` と release logging branch を回避) - v2 系は触らない(C7_SAFE では Pool v2 / Tiny v2 は常時 OFF)。 - FREE_POLICY/THP を触る実験例(現在の HEAD では必須ではなく、組み合わせによっては微マイナスになる場合もある): ```sh diff --git a/docs/analysis/PHASE4_ALLOC_GATE_SPECIALIZATION_NEXT_INSTRUCTIONS.md b/docs/analysis/PHASE4_ALLOC_GATE_SPECIALIZATION_NEXT_INSTRUCTIONS.md index 1fee4f9f..d524ba29 100644 --- a/docs/analysis/PHASE4_ALLOC_GATE_SPECIALIZATION_NEXT_INSTRUCTIONS.md +++ b/docs/analysis/PHASE4_ALLOC_GATE_SPECIALIZATION_NEXT_INSTRUCTIONS.md @@ -13,6 +13,12 @@ Phase 3 は **D1 昇格 / D2 凍結**で完全閉鎖。次の “芯” は allo - Frozen / ignore: - `HAKMEM_WRAP_ENV_CACHE=1`(D2, NO-GO) +## Status(2025-12-13) + +- D3 実装: ✅ 完了(`core/box/tiny_alloc_gate_shape_env_box.h`, `core/box/tiny_alloc_gate_box.h`) +- Mixed A/B(10-run, iter=20M, ws=400): Mean **+0.56%**(Median -0.5%)→ **NEUTRAL** +- 判定: **default OFF の research box として freeze**(本線プリセットへ昇格しない) + ## Step 0: perf で “GO 条件” を満たしているか確認 判定基準: `tiny_alloc_gate_fast` が **self% ≥ 5%**。 @@ -71,3 +77,8 @@ HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ALLOC_GATE_SHAPE=1 \ - NO-GO/NEUTRAL の場合: - D3 は research box として freeze(default OFF) - 本線は汚さない(プリセット昇格はしない) + +## Next(次の指示) + +- `perf report --no-children` で self% ≥ 5% を 1 つ選び、同じ “分岐形(shape)” 最適化を当てる + - 現状の候補: `malloc` / `free` / `tiny_alloc_gate_fast`(ただし D3 は NEUTRAL なので “意味のある形” 以外は追わない) diff --git a/docs/analysis/PHASE4_D3_ALLOC_GATE_SPECIALIZATION_1_DESIGN.md b/docs/analysis/PHASE4_D3_ALLOC_GATE_SPECIALIZATION_1_DESIGN.md index b8ab0e4a..929646ec 100644 --- a/docs/analysis/PHASE4_D3_ALLOC_GATE_SPECIALIZATION_1_DESIGN.md +++ b/docs/analysis/PHASE4_D3_ALLOC_GATE_SPECIALIZATION_1_DESIGN.md @@ -216,6 +216,13 @@ HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ALLOC_GATE_SHAPE=1 \ ./bench_random_mixed_hakmem 20000000 400 1 ``` +### Results(2025-12-13, Release, 10-run) + +- Baseline(`HAKMEM_ALLOC_GATE_SHAPE=0`): Mean **47.55M** ops/s, Median **48.08M** +- Optimized(`HAKMEM_ALLOC_GATE_SHAPE=1`): Mean **47.82M** ops/s, Median **47.84M** +- Δ(Mean): **+0.56%**(Median -0.5%)→ **NEUTRAL** +- 動作確認: `HAKMEM_ALLOC_GATE_SHAPE=1` で `tiny_route_get()` 経由の `[REL_C7_ROUTE]` ログが消える(bypass を確認) + ### Success Criteria **GO**: Mean gain >= +1.0%, Median >= +0.0% @@ -231,6 +238,8 @@ HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE HAKMEM_ALLOC_GATE_SHAPE=1 \ - **Freeze and archive** (default OFF, do not pursue) - Document regression cause, learn for future optimizations +**Decision(この変更)**: **NEUTRAL**(default OFF の research box として保持) + ## 期待値 ### Performance Gain Estimation diff --git a/hakmem.d b/hakmem.d index 16f40684..8cf5ed95 100644 --- a/hakmem.d +++ b/hakmem.d @@ -153,6 +153,7 @@ hakmem.o: core/hakmem.c core/hakmem.h core/hakmem_build_flags.h \ core/box/../front/../box/tiny_metadata_cache_hot_box.h \ core/box/../front/../box/tiny_free_route_cache_env_box.h \ core/box/tiny_alloc_gate_box.h core/box/tiny_route_box.h \ + core/box/tiny_alloc_gate_shape_env_box.h \ core/box/tiny_front_config_box.h core/box/wrapper_env_box.h \ core/box/wrapper_env_cache_box.h core/box/wrapper_env_cache_env_box.h \ core/box/../hakmem_internal.h @@ -387,6 +388,7 @@ core/box/../front/../box/tiny_metadata_cache_hot_box.h: core/box/../front/../box/tiny_free_route_cache_env_box.h: core/box/tiny_alloc_gate_box.h: core/box/tiny_route_box.h: +core/box/tiny_alloc_gate_shape_env_box.h: core/box/tiny_front_config_box.h: core/box/wrapper_env_box.h: core/box/wrapper_env_cache_box.h: