Files
hakmem/core/box/tiny_front_config_box.h
Moe Charm (CI) cfa587c61d Phase 8-Step1-3: Unified Cache hot path optimization (config macro + prewarm + PGO init removal)
Goal: Reduce branches in Unified Cache hot paths (-2 branches per op)
Expected improvement: +2-3% in PGO mode

Changes:
1. Config Macro (Step 1):
   - Added TINY_FRONT_UNIFIED_CACHE_ENABLED macro to tiny_front_config_box.h
   - PGO mode: compile-time constant (1)
   - Normal mode: runtime function call unified_cache_enabled()
   - Replaced unified_cache_enabled() calls in 3 locations:
     * unified_cache_pop() line 142
     * unified_cache_push() line 182
     * unified_cache_pop_or_refill() line 228

2. Function Declaration Fix:
   - Moved unified_cache_enabled() from static inline to non-static
   - Implementation in tiny_unified_cache.c (was in .h as static inline)
   - Forward declaration in tiny_front_config_box.h
   - Resolves declaration conflict between config box and header

3. Prewarm (Step 2):
   - Added unified_cache_init() call to bench_fast_init()
   - Ensures cache is initialized before benchmark starts
   - Enables PGO builds to remove lazy init checks

4. Conditional Init Removal (Step 3):
   - Wrapped lazy init checks in #if !HAKMEM_TINY_FRONT_PGO
   - PGO builds assume prewarm → no init check needed (-1 branch)
   - Normal builds keep lazy init for safety
   - Applied to 3 functions: unified_cache_pop(), unified_cache_push(), unified_cache_pop_or_refill()

Performance Impact:
  PGO mode: -2 branches per operation (enabled check + init check)
  Normal mode: Same as before (runtime checks)

Branch Elimination (PGO):
  Before: if (!unified_cache_enabled()) + if (slots == NULL)
  After:  if (!1) [eliminated] + [init check removed]
  Result: -2 branches in alloc/free hot paths

Files Modified:
  core/box/tiny_front_config_box.h        - Config macro + forward declaration
  core/front/tiny_unified_cache.h         - Config macro usage + PGO conditionals
  core/front/tiny_unified_cache.c         - unified_cache_enabled() implementation
  core/box/bench_fast_box.c               - Prewarm call in bench_fast_init()

Note: BenchFast mode has pre-existing crash (not caused by these changes)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 17:58:42 +09:00

171 lines
7.2 KiB
C

// tiny_front_config_box.h - Phase 4-Step3: Tiny Front Config Box
// Purpose: Compile-time configuration for dead code elimination
// Contract: Dual-mode (compile-time fixed vs. runtime ENV checks)
// Performance: Target +5-8% via branch elimination (57.2M → 60-62M ops/s)
//
// Design Principles (Box Pattern):
// 1. Single Responsibility: Configuration management ONLY
// 2. Clear Contract: PGO mode = compile-time constants, Normal mode = runtime checks
// 3. Observable: Config report function (debug builds)
// 4. Safe: Backward compatible (default runtime mode)
// 5. Testable: Easy A/B comparison (PGO vs normal builds)
//
// Usage:
// Normal build (runtime config, backward compatible):
// make bench_random_mixed_hakmem
//
// PGO build (compile-time config, dead code elimination):
// make CFLAGS="-DHAKMEM_TINY_FRONT_PGO=1" bench_random_mixed_hakmem
//
// Expected Benefit:
// - Dead code elimination: Compiler removes disabled code paths
// - Branch reduction: if (CONSTANT_0) { ... } → eliminated
// - I-cache improvement: Smaller code size (no dead branches)
// - Target: +5-8% improvement (even without PGO profiling)
#ifndef TINY_FRONT_CONFIG_BOX_H
#define TINY_FRONT_CONFIG_BOX_H
#include <stdio.h>
#include "../hakmem_build_flags.h"
// ============================================================================
// Build Flag Check (must be defined in hakmem_build_flags.h)
// ============================================================================
#ifndef HAKMEM_TINY_FRONT_PGO
# define HAKMEM_TINY_FRONT_PGO 0
#endif
// ============================================================================
// PGO Mode: Fixed Configuration (Compile-Time Constants)
// ============================================================================
#if HAKMEM_TINY_FRONT_PGO
// PGO-optimized build: All runtime checks become compile-time constants
// Compiler constant folding eliminates dead branches:
// if (TINY_FRONT_HEAP_V2_ENABLED) { ... } // 0 → entire block removed
// if (!TINY_FRONT_SFC_ENABLED) { ... } // !1 → entire block removed
#define TINY_FRONT_ULTRA_SLIM_ENABLED 0 // Disabled (use normal front)
#define TINY_FRONT_HEAP_V2_ENABLED 0 // Disabled (use Unified Cache)
#define TINY_FRONT_SFC_ENABLED 1 // Enabled (SFC cascade)
#define TINY_FRONT_FASTCACHE_ENABLED 0 // Disabled (use Unified Cache)
#define TINY_FRONT_TLS_SLL_ENABLED 1 // Enabled (TLS SLL freelist)
#define TINY_FRONT_UNIFIED_CACHE_ENABLED 1 // Enabled (Unified Cache - tcache-style)
#define TINY_FRONT_UNIFIED_GATE_ENABLED 1 // Enabled (Front Gate Unification)
#define TINY_FRONT_METRICS_ENABLED 0 // Disabled (no runtime overhead)
#define TINY_FRONT_DIAG_ENABLED 0 // Disabled (no diagnostics)
// Expected code reduction:
// - Ultra SLIM check: 1 branch removed
// - Heap V2 check: 1 branch removed
// - Metrics check: 2-3 branches removed
// - Diag check: 1 branch removed
// Total: 5-7 branches eliminated in hot path
#else
// ============================================================================
// Normal Mode: Runtime Configuration (Backward Compatible)
// ============================================================================
// Normal build: Checks ENV variables or global config state
// Preserves backward compatibility with existing ENV variable interface
//
// NOTE: The actual runtime config functions (ultra_slim_mode_enabled, etc.)
// are defined in their respective modules:
// - front_gate_unified_enabled() → core/front/malloc_tiny_fast.h
// - sfc_cascade_enabled() → core/hakmem_tiny_sfc.h
// - tiny_heap_v2_enabled() → core/front/tiny_heap_v2.h
// - etc.
//
// This config box ONLY defines the macros that expand to function calls.
// The functions themselves are implemented here as static inline to avoid include order issues.
// Phase 7-Step6-Fix: Config wrapper functions (for normal mode)
// These are static inline to access static global variables from any include order
static inline int tiny_fastcache_enabled(void) {
extern int g_fastcache_enable;
return g_fastcache_enable;
}
static inline int tiny_sfc_enabled(void) {
extern int g_sfc_enabled;
return g_sfc_enabled;
}
static inline int tiny_tls_sll_enabled(void) {
extern int g_tls_sll_enable;
return g_tls_sll_enable;
}
// Phase 8-Step1: Unified Cache enabled wrapper
// Forward declaration - actual function is in tiny_unified_cache.c
int unified_cache_enabled(void);
// Config macros (runtime function calls)
// These expand to actual function calls in normal mode
#define TINY_FRONT_ULTRA_SLIM_ENABLED ultra_slim_mode_enabled()
#define TINY_FRONT_HEAP_V2_ENABLED tiny_heap_v2_enabled()
#define TINY_FRONT_SFC_ENABLED tiny_sfc_enabled()
#define TINY_FRONT_FASTCACHE_ENABLED tiny_fastcache_enabled()
#define TINY_FRONT_TLS_SLL_ENABLED tiny_tls_sll_enabled()
#define TINY_FRONT_UNIFIED_CACHE_ENABLED unified_cache_enabled()
#define TINY_FRONT_UNIFIED_GATE_ENABLED front_gate_unified_enabled()
#define TINY_FRONT_METRICS_ENABLED tiny_metrics_enabled()
#define TINY_FRONT_DIAG_ENABLED tiny_diag_enabled()
#endif // HAKMEM_TINY_FRONT_PGO
// ============================================================================
// Configuration Helpers
// ============================================================================
// Check if running in PGO-optimized build
static inline int tiny_front_is_pgo_build(void) {
return HAKMEM_TINY_FRONT_PGO;
}
// Get effective configuration (for diagnostics)
static inline void tiny_front_config_report(void) {
#if !HAKMEM_BUILD_RELEASE
fprintf(stderr, "[TINY_FRONT_CONFIG]\n");
fprintf(stderr, " PGO Build: %d\n", HAKMEM_TINY_FRONT_PGO);
fprintf(stderr, " Ultra SLIM: %d\n", TINY_FRONT_ULTRA_SLIM_ENABLED);
fprintf(stderr, " Heap V2: %d\n", TINY_FRONT_HEAP_V2_ENABLED);
fprintf(stderr, " SFC: %d\n", TINY_FRONT_SFC_ENABLED);
fprintf(stderr, " FastCache: %d\n", TINY_FRONT_FASTCACHE_ENABLED);
fprintf(stderr, " Unified Gate: %d\n", TINY_FRONT_UNIFIED_GATE_ENABLED);
fprintf(stderr, " Metrics: %d\n", TINY_FRONT_METRICS_ENABLED);
fprintf(stderr, " Diag: %d\n", TINY_FRONT_DIAG_ENABLED);
fflush(stderr);
#endif
}
// ============================================================================
// Performance Notes
// ============================================================================
// Expected improvements (Phase 4-Step3):
// - Random Mixed 256: 57.2M → 60-62M ops/s (+5-8%)
// - Tiny Hot 64B: Current → +5-8%
//
// Key optimizations:
// 1. Dead code elimination: Compiler removes disabled code paths
// 2. Branch reduction: if (CONSTANT) → compile-time evaluation
// 3. I-cache improvement: Smaller code size (no dead branches)
// 4. Constant propagation: Compiler optimizes based on known values
//
// Trade-offs:
// 1. Binary size: PGO build is specialized (not configurable at runtime)
// 2. Flexibility: PGO build ignores ENV variables (fixed config)
// 3. Testing: Need separate builds for A/B testing (PGO vs normal)
//
// Recommendation:
// - Development: Use normal build (runtime config, flexible)
// - Production: Use PGO build after profiling (maximum performance)
#endif // TINY_FRONT_CONFIG_BOX_H