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>
134 lines
4.7 KiB
C
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();
|
|
}
|
|
}
|