Files
hakmem/core/box/tiny_static_route_box.c
Moe Charm (CI) d54893ea1d Phase 3 C3: Static Routing A/B Test ADOPT (+2.20% Mixed gain)
Step 2 & 3 Complete:
- A/B test (Mixed 10-run): STATIC_ROUTE=0 (38.91M) → =1 (39.77M) = +2.20% avg
  - Median gain: +1.98%
  - Result:  GO (exceeds +1.0% threshold)

- Decision:  ADOPT into MIXED_TINYV3_C7_SAFE preset
  - bench_profile.h line 77: HAKMEM_TINY_STATIC_ROUTE=1 default
  - Learner auto-disables static route when HAKMEM_SMALL_LEARNER_V7_ENABLED=1

Implementation Summary:
- core/box/tiny_static_route_box.{h,c}: Research box (Step 1A)
- core/front/malloc_tiny_fast.h: Route lookup integration (Step 1B, lines 249-256)
- core/bench_profile.h: Bench sync + preset adoption

Cumulative Phase 2-3 Gains:
- B3 (Routing shape): +2.89%
- B4 (Wrapper split): +1.47%
- C3 (Static routing): +2.20%
- Total: ~6.8% (35.2M → ~39.8M ops/s)

Next: Phase 3 C1 (TLS Prefetch, expected +2-4%)

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-13 18:46:11 +09:00

134 lines
4.7 KiB
C

#define _GNU_SOURCE
#include "tiny_static_route_box.h"
#include "smallobject_policy_v7_box.h"
#include <stdlib.h>
#include <stdatomic.h>
TinyStaticRoute g_tiny_static_route = {.inited = ATOMIC_VAR_INIT(0)};
static _Atomic int static_route_cached_enabled = -1; // -1 = uninitialized
// Check if static routing should be enabled
// (Returns 0 if learner is active, or if ENV is explicitly off)
static inline int static_route_should_be_enabled(void) {
const char* e = getenv("HAKMEM_TINY_STATIC_ROUTE");
// Explicit disable
if (e && *e == '0') return 0;
// If v7 learner is enabled, force disable (static route doesn't track learner updates).
// Mirrors smallobject_policy_v7.c::learner_v7_enabled():
// - If HAKMEM_SMALL_LEARNER_V7_ENABLED=0 → learner disabled
// - Else learner enabled iff HAKMEM_SMALL_HEAP_V7_ENABLED is enabled
{
const char* learner_e = getenv("HAKMEM_SMALL_LEARNER_V7_ENABLED");
if (!(learner_e && *learner_e && *learner_e == '0')) {
const char* v7_e = getenv("HAKMEM_SMALL_HEAP_V7_ENABLED");
if (v7_e && *v7_e && *v7_e != '0') {
return 0; // Learner ON → static route OFF
}
}
}
// Explicit enable or default OFF
return (e && *e != '0') ? 1 : 0;
}
int tiny_static_route_init_once(void) {
// Check if static routing is enabled
if (!static_route_should_be_enabled()) {
atomic_store_explicit(&g_tiny_static_route.inited, 0, memory_order_release);
return 0;
}
int state = atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire);
if (__builtin_expect(state == 1, 1)) {
return 1;
}
if (__builtin_expect(state == -1, 0)) {
while (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == -1) {
__builtin_ia32_pause();
}
return atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == 1;
}
// Try to become the initializer: 0 → -1
int expected = 0;
if (!atomic_compare_exchange_strong_explicit(&g_tiny_static_route.inited, &expected, -1,
memory_order_acq_rel,
memory_order_relaxed)) {
// Someone else is initializing or already initialized
while (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == -1) {
__builtin_ia32_pause();
}
return atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == 1;
}
// We own the initialization
SmallPolicyV7 tmp = {0};
small_policy_v7_init_from_env(&tmp);
// Copy static route table from policy snapshot (no learner update)
for (int i = 0; i < 8; i++) {
g_tiny_static_route.route_kind[i] = tmp.route_kind[i];
}
// Mark as initialized
atomic_store_explicit(&g_tiny_static_route.inited, 1, memory_order_release);
return 1;
}
SmallRouteKind tiny_static_route_get_kind(int class_idx) {
if ((unsigned)class_idx >= 8u) {
return SMALL_ROUTE_LEGACY;
}
if (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) != 1) {
if (!tiny_static_route_init_once()) {
return SMALL_ROUTE_LEGACY;
}
}
return g_tiny_static_route.route_kind[class_idx];
}
void tiny_static_route_refresh_from_env(void) {
// Refresh cached enable flag first (bench_apply_profile sync).
int enabled = static_route_should_be_enabled();
atomic_store_explicit(&static_route_cached_enabled, enabled, memory_order_release);
if (!enabled) {
atomic_store_explicit(&g_tiny_static_route.inited, 0, memory_order_release);
return;
}
// Re-read route table from policy
SmallPolicyV7 tmp = {0};
small_policy_v7_init_from_env(&tmp);
for (int i = 0; i < 8; i++) {
g_tiny_static_route.route_kind[i] = tmp.route_kind[i];
}
atomic_store_explicit(&g_tiny_static_route.inited, 1, memory_order_release);
}
int tiny_static_route_enabled(void) {
int cached = atomic_load_explicit(&static_route_cached_enabled, memory_order_acquire);
if (__builtin_expect(cached >= 0, 1)) {
return cached;
}
int enabled = static_route_should_be_enabled();
atomic_store_explicit(&static_route_cached_enabled, enabled, memory_order_release);
return enabled;
}
__attribute__((constructor(102)))
static void tiny_static_route_ctor(void) {
// Constructor priority 102 runs after wrapper_env_ctor (101)
// Initialize static route table if enabled
if (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) != 1 &&
tiny_static_route_enabled()) {
tiny_static_route_init_once();
}
}