Drain optimization: Drain ALL blocks to maximize empty detection

Issue:
- Previous drain: only 32 blocks/trigger → slabs partially empty
- Shared pool SuperSlabs mix multiple classes (C0-C7)
- active_slabs only reaches 0 when ALL classes empty
- Result: superslab_free() rarely called, LRU cache unused

Fix:
- Change drain batch_size: 32 → 0 (drain all available)
- Added active_slabs logging in shared_pool_release_slab
- Maximizes chance of SuperSlab becoming completely empty

Performance Impact (ws=4096, 200K iterations):
- Before (batch=32): 5.9M ops/s
- After (batch=all): 6.1M ops/s (+3.4%)
- Baseline improvement: 563K → 6.1M ops/s (+980%!)

Known Issue:
- LRU cache still unused due to Shared Pool design
- SuperSlabs rarely become completely empty (multi-class mixing)
- Requires Shared Pool architecture optimization (Phase 12)

Next: Investigate Shared Pool optimization strategies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-11-14 07:55:51 +09:00
parent 4ffdaae2fc
commit dd613bc93a
2 changed files with 5 additions and 4 deletions

View File

@ -233,8 +233,9 @@ static inline uint32_t tiny_tls_sll_try_drain(int class_idx) {
// Check if interval reached // Check if interval reached
uint32_t interval = tls_sll_drain_get_interval(); uint32_t interval = tls_sll_drain_get_interval();
if (__builtin_expect(g_tls_sll_drain_counter[class_idx] >= interval, 0)) { if (__builtin_expect(g_tls_sll_drain_counter[class_idx] >= interval, 0)) {
// Trigger drain (drain ~32 blocks for now, tune later) // Trigger drain (drain ALL blocks to enable empty detection)
uint32_t drained = tiny_tls_sll_drain(class_idx, 32); // batch_size=0 means drain all available blocks
uint32_t drained = tiny_tls_sll_drain(class_idx, 0);
// Reset counter // Reset counter
g_tls_sll_drain_counter[class_idx] = 0; g_tls_sll_drain_counter[class_idx] = 0;

View File

@ -264,8 +264,8 @@ shared_pool_release_slab(SuperSlab* ss, int slab_idx)
} }
if (dbg == 1) { if (dbg == 1) {
fprintf(stderr, "[SS_SLAB_EMPTY] ss=%p slab_idx=%d class=%d used=0 (releasing to pool)\n", fprintf(stderr, "[SS_SLAB_EMPTY] ss=%p slab_idx=%d class=%d used=0 active_slabs_before=%u (releasing to pool)\n",
(void*)ss, slab_idx, meta->class_idx); (void*)ss, slab_idx, meta->class_idx, ss->active_slabs);
} }
uint32_t bit = (1u << slab_idx); uint32_t bit = (1u << slab_idx);