From 270109839abd30c51d20982a5a60273ea0d59e6e Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Sun, 9 Nov 2025 17:11:52 +0900 Subject: [PATCH] Tiny: extend simple batch refill to class5/6; add adopt_bind_if_safe helper and apply in registry scan; branch hints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Refill: class >=5 uses simplified SLL refill favoring linear carve to reduce branching. - Adopt: introduce adopt_bind_if_safe() encapsulating acquire→drain→bind at single boundary; replace inline registry adopt block. - Hints: mark remote pending as unlikely; prefer linear alloc path. A/B (1T, cpu2, 500k iters, HAKMEM_TINY_ASSUME_1T=1) - 256B: cycles ~60.0M, branch‑miss ~11.05%, time ~84.7ms (±2%). - 1024B: cycles ~27.1M, branch‑miss ~11.09%, time ~74.2ms. --- core/hakmem_tiny_refill.inc.h | 4 ++-- core/tiny_superslab_alloc.inc.h | 32 ++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/hakmem_tiny_refill.inc.h b/core/hakmem_tiny_refill.inc.h index 7588d4e9..6ab0637c 100644 --- a/core/hakmem_tiny_refill.inc.h +++ b/core/hakmem_tiny_refill.inc.h @@ -204,8 +204,8 @@ static inline int sll_refill_small_from_ss(int class_idx, int max_take) { TinySlabMeta* meta = tls->meta; if (!meta) return 0; - // Class7 special-case: simple batch refill (favor linear carve, minimal branching) - if (__builtin_expect(class_idx == 7, 0)) { + // Class 5/6/7 special-case: simple batch refill (favor linear carve, minimal branching) + if (__builtin_expect(class_idx >= 5, 0)) { uint32_t sll_cap = sll_cap_for_class(class_idx, (uint32_t)TINY_TLS_MAG_CAP); int room = (int)sll_cap - (int)g_tls_sll_count[class_idx]; if (room <= 0) return 0; diff --git a/core/tiny_superslab_alloc.inc.h b/core/tiny_superslab_alloc.inc.h index 7031c515..b4afaaf0 100644 --- a/core/tiny_superslab_alloc.inc.h +++ b/core/tiny_superslab_alloc.inc.h @@ -133,6 +133,24 @@ static inline void* superslab_alloc_from_slab(SuperSlab* ss, int slab_idx) { return NULL; // Slab is full } +// Adopt helper: acquire → drain → bind (single boundary) – returns 1 on success +static inline int adopt_bind_if_safe(TinyTLSSlab* tls, SuperSlab* ss, int slab_idx, int class_idx) { + uint32_t self_tid = tiny_self_u32(); + SlabHandle h = slab_try_acquire(ss, slab_idx, self_tid); + if (!slab_is_valid(&h)) return 0; + slab_drain_remote_full(&h); + if (__builtin_expect(slab_is_safe_to_bind(&h), 1)) { + // Optional: move a few nodes to Front SLL to boost next hits + tiny_drain_freelist_to_sll_once(h.ss, h.slab_idx, class_idx); + tiny_tls_bind_slab(tls, h.ss, h.slab_idx); + // Ownership now associated with TLS slab; release handle bookkeeping + slab_release(&h); + return 1; + } + slab_release(&h); + return 0; +} + // Phase 6.24 & 7.6: Refill TLS SuperSlab (with unified TLS cache + deferred allocation) static SuperSlab* superslab_refill(int class_idx) { #if HAKMEM_DEBUG_COUNTERS @@ -475,21 +493,11 @@ static SuperSlab* superslab_refill(int class_idx) { if (!ss || ss->magic != SUPERSLAB_MAGIC) continue; // Note: class_idx check is not needed (per-class registry!) - // Pick first slab with freelist (Box 4: 所有権取得 + remote check) + // Pick first slab with freelist (Box 4: adopt boundary helper) int reg_cap = ss_slabs_capacity(ss); - uint32_t self_tid = tiny_self_u32(); for (int s = 0; s < reg_cap; s++) { if (ss->slabs[s].freelist) { - SlabHandle h = slab_try_acquire(ss, s, self_tid); - if (slab_is_valid(&h)) { - slab_drain_remote_full(&h); - if (slab_is_safe_to_bind(&h)) { - tiny_drain_freelist_to_sll_once(h.ss, h.slab_idx, class_idx); - tiny_tls_bind_slab(tls, ss, s); - return ss; - } - slab_release(&h); - } + if (adopt_bind_if_safe(tls, ss, s, class_idx)) return ss; } } }