Perf optimization: Add __builtin_expect hints to hot paths

Problem: Branch mispredictions in allocation hot paths.
Perf analysis suggested adding likely/unlikely hints.

Solution: Added __builtin_expect hints to critical allocation paths:
1. smallmid_is_enabled() - unlikely (disabled by default)
2. sm_ptr/tiny_ptr/pool_ptr/mid_ptr null checks - likely (success expected)

Optimized locations (core/box/hak_alloc_api.inc.h):
- Line 44: smallmid check (unlikely)
- Line 53: smallmid success check (likely)
- Line 81: tiny success check (likely)
- Line 112: pool success check (likely)
- Line 126: mid success check (likely)

Benchmark results (10M iterations × 5 runs, ws=256):
- Before (Opt2): 71.30M ops/s (avg)
- After (Opt3):  72.92M ops/s (avg)
- Improvement: +2.3% (+1.62M ops/s)

Matches Task agent's prediction of +2-3% throughput gain.

Perf analysis: commit 53bc92842
This commit is contained in:
Moe Charm (CI)
2025-11-28 18:04:32 +09:00
parent ccbeb935c5
commit da3f3507b8

View File

@ -40,7 +40,8 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) {
// ENV: HAKMEM_SMALLMID_ENABLE=1 to enable (default: OFF) // ENV: HAKMEM_SMALLMID_ENABLE=1 to enable (default: OFF)
// CRITICAL: Must come BEFORE Tiny to avoid routing conflict // CRITICAL: Must come BEFORE Tiny to avoid routing conflict
// When enabled, auto-adjusts Tiny to C0-C5 (0-255B only) // When enabled, auto-adjusts Tiny to C0-C5 (0-255B only)
if (smallmid_is_enabled() && smallmid_is_in_range(size)) { // PERF_OPT: unlikely hint - smallmid disabled by default
if (__builtin_expect(smallmid_is_enabled() && smallmid_is_in_range(size), 0)) {
#if HAKMEM_DEBUG_TIMING #if HAKMEM_DEBUG_TIMING
HKM_TIME_START(t_smallmid); HKM_TIME_START(t_smallmid);
#endif #endif
@ -48,7 +49,8 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) {
#if HAKMEM_DEBUG_TIMING #if HAKMEM_DEBUG_TIMING
HKM_TIME_END(HKM_CAT_TINY_ALLOC, t_smallmid); HKM_TIME_END(HKM_CAT_TINY_ALLOC, t_smallmid);
#endif #endif
if (sm_ptr) { // PERF_OPT: likely hint - smallmid usually succeeds when enabled
if (__builtin_expect(sm_ptr != NULL, 1)) {
hkm_ace_track_alloc(); hkm_ace_track_alloc();
return sm_ptr; return sm_ptr;
} }
@ -75,7 +77,8 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) {
#if HAKMEM_DEBUG_TIMING #if HAKMEM_DEBUG_TIMING
HKM_TIME_END(HKM_CAT_TINY_ALLOC, t_tiny); HKM_TIME_END(HKM_CAT_TINY_ALLOC, t_tiny);
#endif #endif
if (tiny_ptr) { hkm_ace_track_alloc(); return tiny_ptr; } // PERF_OPT: likely hint - tiny allocations usually succeed (hot path)
if (__builtin_expect(tiny_ptr != NULL, 1)) { hkm_ace_track_alloc(); return tiny_ptr; }
// PHASE 7 CRITICAL FIX: No malloc fallback for Tiny failures // PHASE 7 CRITICAL FIX: No malloc fallback for Tiny failures
// If Tiny fails for size <= tiny_get_max_size(), let it flow to Mid/ACE layers // If Tiny fails for size <= tiny_get_max_size(), let it flow to Mid/ACE layers
@ -105,7 +108,8 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) {
// Phase 1: Ultra-fast Pool TLS for 8KB-52KB range // Phase 1: Ultra-fast Pool TLS for 8KB-52KB range
if (size >= 8192 && size <= 53248) { if (size >= 8192 && size <= 53248) {
void* pool_ptr = pool_alloc(size); void* pool_ptr = pool_alloc(size);
if (pool_ptr) return pool_ptr; // PERF_OPT: likely hint - pool allocations usually succeed
if (__builtin_expect(pool_ptr != NULL, 1)) return pool_ptr;
// Fall through to existing Mid allocator as fallback // Fall through to existing Mid allocator as fallback
} }
#endif #endif
@ -118,7 +122,8 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) {
#if HAKMEM_DEBUG_TIMING #if HAKMEM_DEBUG_TIMING
HKM_TIME_END(HKM_CAT_POOL_GET, t_mid); HKM_TIME_END(HKM_CAT_POOL_GET, t_mid);
#endif #endif
if (mid_ptr) return mid_ptr; // PERF_OPT: likely hint - mid allocations usually succeed
if (__builtin_expect(mid_ptr != NULL, 1)) return mid_ptr;
} }
#if HAKMEM_FEATURE_EVOLUTION #if HAKMEM_FEATURE_EVOLUTION