Phase 21-1-C: Ring cache Refill/Cascade + Metrics - SLL → Ring cascade

**実装内容**:
- Alloc miss → refill: ring_refill_from_sll() (32 blocks from TLS SLL)
- Free full → fallback: 既に Phase 21-1-B で実装済み(Ring full → TLS SLL)
- Metrics 追加: hit/miss/push/full/refill カウンタ(Phase 19-1 スタイル)
- Stats 出力: ring_cache_print_stats() を bench_random_mixed.c から呼び出し

**修正内容**:
- tiny_alloc_fast.inc.h: Ring miss 時に ring_refill_from_sll() 呼び出し、retry
- tiny_ring_cache.h: Metrics カウンタ追加(pop/push で更新)
- tiny_ring_cache.c: tls_sll_box.h をインクルード、refill カウンタ追加
- bench_random_mixed.c: ring_cache_print_stats() 呼び出し

**ENV 変数**:
- HAKMEM_TINY_HOT_RING_ENABLE=1: Ring 有効化
- HAKMEM_TINY_HOT_RING_CASCADE=1: Refill 有効化(SLL → Ring)
- HAKMEM_TINY_HOT_RING_C2=128: C2 サイズ(default: 128)
- HAKMEM_TINY_HOT_RING_C3=128: C3 サイズ(default: 128)

**動作確認**:
- Ring ON + CASCADE ON: 836K ops/s (10K iterations) 
- クラッシュなし、正常動作

**次のステップ**: Phase 21-1-D (A/B テスト)
This commit is contained in:
Moe Charm (CI)
2025-11-16 08:15:30 +09:00
parent fdbdcdcdb3
commit eb12044416
4 changed files with 115 additions and 17 deletions

View File

@ -41,12 +41,24 @@ typedef struct {
} TinyRingCache;
// ============================================================================
// External TLS Variables (defined in hakmem_tiny.c)
// External TLS Variables (defined in tiny_ring_cache.c)
// ============================================================================
extern __thread TinyRingCache g_ring_cache_c2;
extern __thread TinyRingCache g_ring_cache_c3;
// ============================================================================
// Metrics (Phase 21-1-E, optional for Phase 21-1-C)
// ============================================================================
#if !HAKMEM_BUILD_RELEASE
extern __thread uint64_t g_ring_cache_hit[8]; // Alloc hits
extern __thread uint64_t g_ring_cache_miss[8]; // Alloc misses
extern __thread uint64_t g_ring_cache_push[8]; // Free pushes
extern __thread uint64_t g_ring_cache_full[8]; // Free full (fallback to SLL)
extern __thread uint64_t g_ring_cache_refill[8]; // Refill count (SLL → Ring)
#endif
// ============================================================================
// ENV Control (cached, lazy init)
// ============================================================================
@ -160,6 +172,9 @@ static inline void* ring_cache_pop(int class_idx) {
// Empty check
if (__builtin_expect(ring->head == ring->tail, 0)) {
#if !HAKMEM_BUILD_RELEASE
g_ring_cache_miss[class_idx]++;
#endif
return NULL; // Empty
}
@ -167,6 +182,10 @@ static inline void* ring_cache_pop(int class_idx) {
void* base = ring->slots[ring->head];
ring->head = (ring->head + 1) & ring->mask; // Fast modulo (power of 2)
#if !HAKMEM_BUILD_RELEASE
g_ring_cache_hit[class_idx]++;
#endif
return base; // Return BASE pointer
}
@ -191,6 +210,9 @@ static inline int ring_cache_push(int class_idx, void* base) {
// Full check (leave 1 slot empty to distinguish full/empty)
if (__builtin_expect(next_tail == ring->head, 0)) {
#if !HAKMEM_BUILD_RELEASE
g_ring_cache_full[class_idx]++;
#endif
return 0; // Full
}
@ -198,6 +220,10 @@ static inline int ring_cache_push(int class_idx, void* base) {
ring->slots[ring->tail] = base;
ring->tail = next_tail;
#if !HAKMEM_BUILD_RELEASE
g_ring_cache_push[class_idx]++;
#endif
return 1; // SUCCESS
}