Tiny: extend simple batch refill to class5/6; add adopt_bind_if_safe helper and apply in registry scan; branch hints
- 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.
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user