Phase 15 v1: UnifiedCache FIFO→LIFO NEUTRAL (-0.70% Mixed, +0.42% C7)
Transform existing array-based UnifiedCache from FIFO ring to LIFO stack.
A/B Results:
- Mixed (16-1024B): -0.70% (52,965,966 → 52,593,948 ops/s)
- C7-only (1025-2048B): +0.42% (78,010,783 → 78,335,509 ops/s)
Verdict: NEUTRAL (both below +1.0% GO threshold) - freeze as research box
Implementation:
- L0 ENV gate: tiny_unified_lifo_env_box.{h,c} (HAKMEM_TINY_UNIFIED_LIFO=0/1)
- L1 LIFO ops: tiny_unified_lifo_box.h (unified_cache_try_pop/push_lifo)
- L2 integration: tiny_front_hot_box.h (mode check at entry)
- Reuses existing slots[] array (no intrusive pointers)
Root Causes:
1. Mode check overhead (tiny_unified_lifo_enabled() call)
2. Minimal LIFO vs FIFO locality delta in practice
3. Existing FIFO ring already well-optimized
Bonus Fix: LTO bug for tiny_c7_preserve_header_enabled() (Phase 13/14 latent issue)
- Converted static inline to extern + non-inline implementation
- Fixes undefined reference during LTO linking
Design: docs/analysis/PHASE15_UNIFIEDCACHE_LIFO_1_DESIGN.md
Results: docs/analysis/PHASE15_UNIFIEDCACHE_LIFO_1_AB_TEST_RESULTS.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -30,6 +30,7 @@
|
||||
#include "../tiny_region_id.h"
|
||||
#include "../front/tiny_unified_cache.h" // For TinyUnifiedCache
|
||||
#include "tiny_header_box.h" // Phase 5 E5-2: For tiny_header_finalize_alloc
|
||||
#include "tiny_unified_lifo_box.h" // Phase 15 v1: UnifiedCache FIFO→LIFO
|
||||
|
||||
// ============================================================================
|
||||
// Branch Prediction Macros (Pointer Safety - Prediction Hints)
|
||||
@ -107,12 +108,34 @@
|
||||
//
|
||||
__attribute__((always_inline))
|
||||
static inline void* tiny_hot_alloc_fast(int class_idx) {
|
||||
// Phase 15 v1: Mode check at entry (once per call, not scattered in hot path)
|
||||
int lifo_mode = tiny_unified_lifo_enabled();
|
||||
|
||||
extern __thread TinyUnifiedCache g_unified_cache[];
|
||||
|
||||
// TLS cache access (1 cache miss)
|
||||
// NOTE: Range check removed - caller (hak_tiny_size_to_class) guarantees valid class_idx
|
||||
TinyUnifiedCache* cache = &g_unified_cache[class_idx];
|
||||
|
||||
// Phase 15 v1: LIFO vs FIFO mode switch
|
||||
if (lifo_mode) {
|
||||
// === LIFO MODE: Stack-based (LIFO) ===
|
||||
// Try pop from stack (tail is stack depth)
|
||||
void* base = unified_cache_try_pop_lifo(class_idx);
|
||||
if (__builtin_expect(base != NULL, 1)) {
|
||||
TINY_HOT_METRICS_HIT(class_idx);
|
||||
#if HAKMEM_TINY_HEADER_CLASSIDX
|
||||
return tiny_header_finalize_alloc(base, class_idx);
|
||||
#else
|
||||
return base;
|
||||
#endif
|
||||
}
|
||||
// LIFO miss → fall through to cold path
|
||||
TINY_HOT_METRICS_MISS(class_idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// === FIFO MODE: Ring-based (existing) ===
|
||||
// Branch 1: Cache empty check (LIKELY hit)
|
||||
// Hot path: cache has objects (head != tail)
|
||||
// Cold path: cache empty (head == tail) → refill needed
|
||||
@ -164,12 +187,35 @@ static inline void* tiny_hot_alloc_fast(int class_idx) {
|
||||
//
|
||||
__attribute__((always_inline))
|
||||
static inline int tiny_hot_free_fast(int class_idx, void* base) {
|
||||
// Phase 15 v1: Mode check at entry (once per call, not scattered in hot path)
|
||||
int lifo_mode = tiny_unified_lifo_enabled();
|
||||
|
||||
extern __thread TinyUnifiedCache g_unified_cache[];
|
||||
|
||||
// TLS cache access (1 cache miss)
|
||||
// NOTE: Range check removed - caller guarantees valid class_idx
|
||||
TinyUnifiedCache* cache = &g_unified_cache[class_idx];
|
||||
|
||||
// Phase 15 v1: LIFO vs FIFO mode switch
|
||||
if (lifo_mode) {
|
||||
// === LIFO MODE: Stack-based (LIFO) ===
|
||||
// Try push to stack (tail is stack depth)
|
||||
if (unified_cache_try_push_lifo(class_idx, base)) {
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
extern __thread uint64_t g_unified_cache_push[];
|
||||
g_unified_cache_push[class_idx]++;
|
||||
#endif
|
||||
return 1; // SUCCESS
|
||||
}
|
||||
// LIFO overflow → fall through to cold path
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
extern __thread uint64_t g_unified_cache_full[];
|
||||
g_unified_cache_full[class_idx]++;
|
||||
#endif
|
||||
return 0; // FULL
|
||||
}
|
||||
|
||||
// === FIFO MODE: Ring-based (existing) ===
|
||||
// Calculate next tail (for full check)
|
||||
uint16_t next_tail = (cache->tail + 1) & cache->mask;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user