Phase 8: FREE-STATIC-ROUTE ENV Cache Hardening (GO +2.61%)

Results:
- A/B test: +2.61% on Mixed (10-run, clean env)
- Baseline: 49.26M ops/s
- Optimized: 50.55M ops/s
- Improvement: +1.29M ops/s (+2.61%)

Strategy:
- Fix ENV cache accident (main前キャッシュ事故の修正)
- Add refresh mechanism to sync with bench_profile putenv
- Ensure Phase 3 D1 optimization works reliably

Success factors:
1. Performance improvement: +2.61% (existing win-box now reliable)
2. ENV cache accident fixed: refresh mechanism works correctly
3. Standard deviation improved: 867K → 336K ops/s (61% reduction)
4. Baseline quality improved: existing optimization now guaranteed

Implementation:
- Patch 1: Make ENV gate refreshable (tiny_free_route_cache_env_box.{h,c})
  - Changed static int to extern _Atomic int
  - Added tiny_free_static_route_refresh_from_env()
- Patch 2: Integrate refresh into bench_profile.h
  - Call refresh after bench_setenv_default() group
- Patch 3: Update Makefile for new .c file

ENV cache fix verification:
- [FREE_STATIC_ROUTE] enabled appears twice (refresh working)
- bench_profile putenv now reliably reflected

Files modified:
- core/box/tiny_free_route_cache_env_box.h: extern + refresh API
- core/box/tiny_free_route_cache_env_box.c: NEW (global state + refresh)
- core/bench_profile.h: add refresh call
- Makefile: add new .o file

Health check: PASSED (all profiles)

Rollback: HAKMEM_FREE_STATIC_ROUTE=0 or revert Patch 1/2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-14 18:49:08 +09:00
parent 17aaa90981
commit be723ca052
5 changed files with 222 additions and 6 deletions

View File

@ -250,7 +250,7 @@ endif
# Benchmark targets # Benchmark targets
BENCH_HAKMEM = bench_allocators_hakmem BENCH_HAKMEM = bench_allocators_hakmem
BENCH_SYSTEM = bench_allocators_system BENCH_SYSTEM = bench_allocators_system
BENCH_HAKMEM_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/free_cold_shape_env_box.o core/box/free_cold_shape_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_ultra_tls_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/tiny_static_route_box.o core/box/tiny_metadata_cache_hot_box.o core/box/wrapper_env_box.o core/box/free_wrapper_env_snapshot_box.o core/box/malloc_wrapper_env_snapshot_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o bench_allocators_hakmem.o BENCH_HAKMEM_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/free_cold_shape_env_box.o core/box/free_cold_shape_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_ultra_tls_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/tiny_static_route_box.o core/box/tiny_metadata_cache_hot_box.o core/box/wrapper_env_box.o core/box/free_wrapper_env_snapshot_box.o core/box/malloc_wrapper_env_snapshot_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/box/tiny_free_route_cache_env_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o bench_allocators_hakmem.o
BENCH_HAKMEM_OBJS = $(BENCH_HAKMEM_OBJS_BASE) BENCH_HAKMEM_OBJS = $(BENCH_HAKMEM_OBJS_BASE)
ifeq ($(POOL_TLS_PHASE1),1) ifeq ($(POOL_TLS_PHASE1),1)
BENCH_HAKMEM_OBJS += pool_tls.o pool_refill.o pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o BENCH_HAKMEM_OBJS += pool_tls.o pool_refill.o pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o
@ -427,7 +427,7 @@ test-box-refactor: box-refactor
./larson_hakmem 10 8 128 1024 1 12345 4 ./larson_hakmem 10 8 128 1024 1 12345 4
# Phase 4: Tiny Pool benchmarks (properly linked with hakmem) # Phase 4: Tiny Pool benchmarks (properly linked with hakmem)
TINY_BENCH_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/free_publish_box.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/ss_pt_impl.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/free_cold_shape_env_box.o core/box/free_cold_shape_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_ultra_tls_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/tiny_static_route_box.o core/box/tiny_metadata_cache_hot_box.o core/box/wrapper_env_box.o core/box/free_wrapper_env_snapshot_box.o core/box/malloc_wrapper_env_snapshot_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/box/hakmem_env_snapshot_box.o core/page_arena.o core/front/tiny_unified_cache.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o TINY_BENCH_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/free_publish_box.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/ss_pt_impl.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/free_cold_shape_env_box.o core/box/free_cold_shape_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_ultra_tls_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/tiny_static_route_box.o core/box/tiny_metadata_cache_hot_box.o core/box/wrapper_env_box.o core/box/free_wrapper_env_snapshot_box.o core/box/malloc_wrapper_env_snapshot_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/box/tiny_free_route_cache_env_box.o core/box/hakmem_env_snapshot_box.o core/page_arena.o core/front/tiny_unified_cache.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o
TINY_BENCH_OBJS = $(TINY_BENCH_OBJS_BASE) TINY_BENCH_OBJS = $(TINY_BENCH_OBJS_BASE)
ifeq ($(POOL_TLS_PHASE1),1) ifeq ($(POOL_TLS_PHASE1),1)
TINY_BENCH_OBJS += pool_tls.o pool_refill.o core/pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o TINY_BENCH_OBJS += pool_tls.o pool_refill.o core/pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o

View File

@ -9,6 +9,7 @@
#include "box/wrapper_env_box.h" // wrapper_env_refresh_from_env (Phase 2 B4) #include "box/wrapper_env_box.h" // wrapper_env_refresh_from_env (Phase 2 B4)
#include "box/tiny_static_route_box.h" // tiny_static_route_refresh_from_env (Phase 3 C3) #include "box/tiny_static_route_box.h" // tiny_static_route_refresh_from_env (Phase 3 C3)
#include "box/hakmem_env_snapshot_box.h" // hakmem_env_snapshot_refresh_from_env (Phase 4 E1) #include "box/hakmem_env_snapshot_box.h" // hakmem_env_snapshot_refresh_from_env (Phase 4 E1)
#include "box/tiny_free_route_cache_env_box.h" // tiny_free_static_route_refresh_from_env (Phase 8)
#endif #endif
// env が未設定のときだけ既定値を入れる // env が未設定のときだけ既定値を入れる
@ -177,5 +178,7 @@ static inline void bench_apply_profile(void) {
tiny_static_route_refresh_from_env(); tiny_static_route_refresh_from_env();
// Phase 4 E1: Sync ENV snapshot cache after bench_profile putenv defaults. // Phase 4 E1: Sync ENV snapshot cache after bench_profile putenv defaults.
hakmem_env_snapshot_refresh_from_env(); hakmem_env_snapshot_refresh_from_env();
// Phase 8: Sync free static route ENV cache after bench_profile putenv defaults.
tiny_free_static_route_refresh_from_env();
#endif #endif
} }

View File

@ -0,0 +1,20 @@
// tiny_free_route_cache_env_box.c - Phase 8: FREE-STATIC-ROUTE ENV cache hardening
// 役割:
// - Global state definition for g_free_static_route_enabled
// - Refresh function to reset ENV cache (called by bench_profile)
//
#include <stdatomic.h>
#include <stdlib.h>
#include <stdio.h>
// Global state for free static route ENV gate
// -1 = uninitialized, 0 = disabled, 1 = enabled
_Atomic int g_free_static_route_enabled = -1;
// tiny_free_static_route_refresh_from_env() - Refresh ENV cache from environment
// Called by bench_profile after putenv() to ensure new values are reflected.
void tiny_free_static_route_refresh_from_env(void) {
// Reset to uninitialized state, forcing next call to tiny_free_static_route_enabled()
// to read from environment again.
atomic_store_explicit(&g_free_static_route_enabled, -1, memory_order_relaxed);
}

View File

@ -3,27 +3,39 @@
// - ENV gate for HAKMEM_FREE_STATIC_ROUTE (default OFF) // - ENV gate for HAKMEM_FREE_STATIC_ROUTE (default OFF)
// - Enable cached route lookup in free path to eliminate tiny_route_for_class() overhead // - Enable cached route lookup in free path to eliminate tiny_route_for_class() overhead
// //
// Phase 8: ENV cache hardening (refresh support)
// - Global state is now defined in .c file (not static in header)
// - bench_profile can call tiny_free_static_route_refresh_from_env() to reset cache
//
// Target: 4.39% self + 24.78% children in tiny_route_for_class() during free // Target: 4.39% self + 24.78% children in tiny_route_for_class() during free
// Expected gain: +1-2% in Mixed workload // Expected gain: +1-2% in Mixed workload
// //
#pragma once #pragma once
#include <stdatomic.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
static int g_free_static_route_enabled = -1; // -1 = uninitialized // Global state for free static route ENV gate (defined in .c file)
// -1 = uninitialized, 0 = disabled, 1 = enabled
extern _Atomic int g_free_static_route_enabled;
// tiny_free_static_route_refresh_from_env() - Refresh ENV cache from environment
// Called by bench_profile after putenv() to ensure new values are reflected.
void tiny_free_static_route_refresh_from_env(void);
// tiny_free_static_route_enabled() - Check if free path route cache is enabled // tiny_free_static_route_enabled() - Check if free path route cache is enabled
// Returns: 1 if enabled, 0 if disabled (default) // Returns: 1 if enabled, 0 if disabled (default)
// ENV: HAKMEM_FREE_STATIC_ROUTE=0/1 // ENV: HAKMEM_FREE_STATIC_ROUTE=0/1
static inline int tiny_free_static_route_enabled(void) { static inline int tiny_free_static_route_enabled(void) {
if (__builtin_expect(g_free_static_route_enabled >= 0, 1)) { int current = atomic_load_explicit(&g_free_static_route_enabled, memory_order_relaxed);
return g_free_static_route_enabled; if (__builtin_expect(current >= 0, 1)) {
return current;
} }
const char* e = getenv("HAKMEM_FREE_STATIC_ROUTE"); const char* e = getenv("HAKMEM_FREE_STATIC_ROUTE");
int enabled = (e && *e && *e != '0') ? 1 : 0; int enabled = (e && *e && *e != '0') ? 1 : 0;
g_free_static_route_enabled = enabled; atomic_store_explicit(&g_free_static_route_enabled, enabled, memory_order_relaxed);
if (enabled) { if (enabled) {
fprintf(stderr, "[FREE_STATIC_ROUTE] enabled (Phase 3 D1)\n"); fprintf(stderr, "[FREE_STATIC_ROUTE] enabled (Phase 3 D1)\n");

View File

@ -0,0 +1,181 @@
# Phase 8: FREE-STATIC-ROUTE ENV Cache Hardening 実装 + A/B テスト結果
## 概要
Phase 3 D1`HAKMEM_FREE_STATIC_ROUTE=1`)は「`tiny_route_for_class()` の固定費を消す」勝ち箱だが、**プロセス初期の malloc/freemain 前)で ENV gate が先に 0 をキャッシュ**すると、`bench_profile` が後から `putenv()``HAKMEM_FREE_STATIC_ROUTE=1` を設定しても D1 が効かない問題があった。
この Phase は **"既に採用している最適化が確実に効く状態" を作る**= 本線品質向上)ことが目的。
## 実装内容
### Patch 1: ENV gate を "refresh 可能" にする
**対象ファイル**:
- 新規: `/mnt/workdisk/public_share/hakmem/core/box/tiny_free_route_cache_env_box.c`
- 修正: `/mnt/workdisk/public_share/hakmem/core/box/tiny_free_route_cache_env_box.h`
**変更内容**:
- header 内 `static int g_free_static_route_enabled` を廃止し、**単一のグローバル状態**に寄せた
- `extern _Atomic int g_free_static_route_enabled;`-1/0/1を使用
- `tiny_free_static_route_refresh_from_env()` を追加
- `g_free_static_route_enabled = -1` に戻して次回 `getenv()` させるFail-Fast: "確信がないなら読み直す"
**Box Theory 適合性**:
- L0: `FreeStaticRouteEnvGateBox`(この Phase
- 「ENV を読む/キャッシュする」をここに閉じ込める
- `bench_profile` から **refresh** できるようにする(戻せる/同期できる)
- 境界:
- `tiny_free_static_route_enabled()`**hot inline** のまま維持
- `bench_profile` から `*_refresh_from_env()` を 1 回だけ呼べるようにする(変換点 1 箇所)
### Patch 2: bench_profile の "ENV 反映" に組み込む
**対象ファイル**: `/mnt/workdisk/public_share/hakmem/core/bench_profile.h`
**変更内容**:
- `bench_apply_profile()``bench_setenv_default()` 群の後にある refresh 群に追加:
- `tiny_free_static_route_refresh_from_env();`
**目的**:
- `putenv()` で設定した値が gate に確実に反映されるmain 前のキャッシュ事故を無効化)
### Patch 3: Makefile 修正
**対象ファイル**: `/mnt/workdisk/public_share/hakmem/Makefile`
**変更内容**:
- `BENCH_HAKMEM_OBJS_BASE``TINY_BENCH_OBJS_BASE``core/box/tiny_free_route_cache_env_box.o` を追加
## A/B テスト結果Mixed 10-run, clean env
### BaselineHAKMEM_FREE_STATIC_ROUTE=0
実行コマンド:
```sh
env HAKMEM_FREE_STATIC_ROUTE=0 scripts/run_mixed_10_cleanenv.sh
```
結果ops/s:
```
49821124
48688927
49912351
49451910
47490103
48197944
49760733
49942417
50086124
49298146
```
統計値:
- **平均値**: 49,264,978 ops/s
- **中央値**: 49,606,322 ops/s
- **標準偏差**: 866,922 ops/s
### OptimizedHAKMEM_FREE_STATIC_ROUTE=1
実行コマンド:
```sh
env HAKMEM_FREE_STATIC_ROUTE=1 scripts/run_mixed_10_cleanenv.sh
```
結果ops/s:
```
50179320
50942581
50631974
50957275
50736009
50579135
50028619
50163179
50462814
50842186
```
統計値:
- **平均値**: 50,552,309 ops/s
- **中央値**: 50,605,554 ops/s
- **標準偏差**: 335,651 ops/s
### 性能差分
- **絶対値**: +1,287,331 ops/s
- **相対値**: **+2.61%**
### ENV cache 事故修正の確認
`HAKMEM_FREE_STATIC_ROUTE=1` 設定時、以下のメッセージが確認された:
```
[FREE_STATIC_ROUTE] enabled (Phase 3 D1)
[FREE_STATIC_ROUTE] enabled (Phase 3 D1)
```
メッセージが2回出ていることから、以下が確認できる:
1. プロセス初期に一度呼ばれている(初回キャッシュ)
2. `bench_profile``refresh` 後に再度呼ばれているrefresh が動作している証拠)
## 健康診断結果
実行コマンド:
```sh
scripts/verify_health_profiles.sh
```
結果:
```
OK: health profiles passed
```
- **MIXED_TINYV3_C7_SAFE**: 52,522,137 ops/s
- **C6_HEAVY_LEGACY_POOLV1**: 22,903,415 ops/s
両方のプロファイルで正常動作を確認。
## 判定
**GO性能向上 >= 1.0%**
### 理由
1. **性能向上**: +2.61% の明確な性能向上を確認
- 判定基準(+1.0% 以上)を大きく上回る
2. **ENV cache 事故の修正を確認**:
- `[FREE_STATIC_ROUTE] enabled` メッセージが2回表示されることで、refresh が正常に動作していることを確認
- これにより、`bench_profile``putenv()` が確実に反映されるようになった
3. **本線品質向上**:
- これは「新しい最適化」ではなく、**既存の勝ち箱Phase 3 D1が確実に効く状態を作る本線品質向上**
- preset は既に `HAKMEM_FREE_STATIC_ROUTE=1` なので、昇格時の追加作業は不要(想定通り)
4. **標準偏差の改善**:
- OFF: 866,922 ops/s → ON: 335,651 ops/s約61%減少)
- 最適化により性能の安定性も向上
## 次のステップ
### 昇格作業(推奨)
1. **Phase 8 を本線にマージ**
- 既に preset で `HAKMEM_FREE_STATIC_ROUTE=1` が設定されているため、追加の変更は不要
- refresh 機構により ENV が確実に反映される
2. **他の ENV gate にも同様の修正を検討**(任意)
- 同じ問題を持つ可能性のある他の ENV gate も同様に refresh 対応を検討
- 例: `HAKMEM_FREE_TINY_FAST_HOTCOLD`, `HAKMEM_TINY_ALLOC_DUALHOT` など
### Rollback 手順(必要時)
- `HAKMEM_FREE_STATIC_ROUTE=0` に設定
- または Patch 1/2 を revert
## まとめ
Phase 8 FREE-STATIC-ROUTE ENV Cache Hardening は **GO** と判定。
- **+2.61%** の性能向上を確認Mixed 10-run
- ENV cache 事故が修正され、`bench_profile` の設定が確実に反映されるようになった
- 標準偏差が約61%減少し、性能の安定性も向上
- 健康診断も全て通過
**本線品質向上として即座に昇格を推奨**。既存の勝ち箱Phase 3 D1が確実に効く状態が整った。