Files
hakmem/core/box/smallobject_hotbox_v5_box.h
Moe Charm (CI) 8789542a9f Phase v5-7: C6 ULTRA pattern (research mode, 32-slot TLS freelist)
Implementation:
- ENV: HAKMEM_SMALL_HEAP_V5_ULTRA_C6_ENABLED=0|1 (default: 0)
- SmallHeapCtxV5: added c6_tls_freelist[32], c6_tls_count, ultra_c6_enabled
- small_segment_v5_owns_ptr_fast(): lightweight segment check for free path
- small_alloc_slow_v5_c6_refill(): batch TLS fill from page freelist
- small_free_slow_v5_c6_drain(): drain half of TLS to page on overflow

Performance (C6-heavy 257-768B, 2M iters, ws=400):
- v5 OFF baseline: 47M ops/s
- v5 ULTRA: 37-38M ops/s (-20%)
- vs v5 base (no opts): +3-5% improvement

Design limitation identified:
- Header write required on every alloc (freelist overwrites header byte)
- Segment validation required on every free
- page->used tracking required for retirement
- These prevent matching baseline pool v1 performance

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 13:32:46 +09:00

155 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// smallobject_hotbox_v5_box.h - SmallObject HotBox v5 型定義Phase v5-0
//
// この段階では型とインターフェース定義のみ。挙動は変わらない。
#ifndef HAKMEM_SMALLOBJECT_HOTBOX_V5_BOX_H
#define HAKMEM_SMALLOBJECT_HOTBOX_V5_BOX_H
#include <stdint.h>
#include <stdbool.h>
#define NUM_SMALL_CLASSES_V5 8 // C0C7
// SmallPageMetaV5: v5 ページメタデータ
// Hot fields (alloc/free 頻繁アクセス) を先頭に集約L1 cache 最適化)
typedef struct SmallPageMetaV5 {
// Hot fields (alloc/free 頻繁アクセス)
void* free_list; // フリーリスト先頭 (offset 0)
uint16_t used; // 使用中ブロック数 (offset 8)
uint16_t capacity; // このページの総容量 (offset 10)
// Metadata初期化時のみ
uint8_t class_idx; // size class index (offset 12)
uint8_t flags; // reserved (offset 13)
uint16_t page_idx; // segment 内でのページインデックス (offset 14)
void* segment; // SmallSegmentV5* への backpointer (offset 16)
// Intrusive list field for current/partial/full lists (Phase v5-2)
struct SmallPageMetaV5* next; // next page in list (offset 24)
} SmallPageMetaV5; // total 32B
// SmallClassHeapV5: サイズクラス毎のホットヒープ状態
typedef struct SmallClassHeapV5 {
SmallPageMetaV5* current; // 現在のページalloc 中)
SmallPageMetaV5* partial_head; // partial ページリスト
SmallPageMetaV5* full_head; // full ページリスト
uint32_t partial_count; // partial ページ数
} SmallClassHeapV5;
// Phase v5-6: TLS batch structure (C6-only batching)
#define SMALL_V5_BATCH_CAP 4
typedef struct SmallV5Batch {
void* slots[SMALL_V5_BATCH_CAP]; // BASE ポインタ
uint8_t count;
} SmallV5Batch;
// Phase v5-7: C6 ULTRA TLS freelist capacity
#define SMALL_V5_ULTRA_C6_CAP 32
// SmallHeapCtxV5: per-thread ホットヒープコンテキスト
typedef struct SmallHeapCtxV5 {
SmallClassHeapV5 cls[NUM_SMALL_CLASSES_V5];
uint8_t header_mode; // Phase v5-4: FULL or LIGHT (cached from ENV)
bool tls_cache_enabled; // Phase v5-5: TLS cache enabled flag (cached from ENV)
void* c6_cached_block; // Phase v5-5: C6 TLS cache (1-slot cache)
bool batch_enabled; // Phase v5-6: Batch enabled flag (cached from ENV)
SmallV5Batch c6_batch; // Phase v5-6: C6 TLS batch (4-slot buffer)
// Phase v5-7: C6 ULTRA TLS freelist
bool ultra_c6_enabled; // cached from ENV
void* c6_tls_freelist[SMALL_V5_ULTRA_C6_CAP]; // 32-slot TLS freelist
uint8_t c6_tls_count; // current slot count
} SmallHeapCtxV5;
// ============================================================================
// C6 class configuration (Phase v5-3)
// ============================================================================
#define SMALL_HEAP_V5_C6_CLASS_IDX 6
#define SMALL_HEAP_V5_C6_BLOCK_SIZE 512
#define SMALL_HEAP_V5_C6_PARTIAL_LIMIT 1
// Helper function for partial limit (future extensibility)
static inline uint32_t small_heap_v5_partial_limit(uint32_t class_idx) {
// C6 only in v5-2/v5-3
return (class_idx == SMALL_HEAP_V5_C6_CLASS_IDX) ? SMALL_HEAP_V5_C6_PARTIAL_LIMIT : 0u;
}
// ============================================================================
// Page list operations (v5-3 refactor)
// ============================================================================
#define SMALL_PAGE_V5_PUSH_PARTIAL(h, page) \
do { \
if ((h) && (page)) { \
(page)->next = (h)->partial_head; \
(h)->partial_head = (page); \
(h)->partial_count++; \
} \
} while (0)
#define SMALL_PAGE_V5_POP_PARTIAL(h) \
({ SmallPageMetaV5* _p = (h) ? (h)->partial_head : NULL; \
if (_p && (h)) { \
(h)->partial_head = _p->next; \
_p->next = NULL; \
if ((h)->partial_count > 0) { \
(h)->partial_count--; \
} \
} \
_p; \
})
#define SMALL_PAGE_V5_PUSH_FULL(h, page) \
do { \
if ((h) && (page)) { \
(page)->next = (h)->full_head; \
(h)->full_head = (page); \
} \
} while (0)
// Page location in heap lists
typedef enum {
LOC_NONE = 0,
LOC_CURRENT,
LOC_PARTIAL,
LOC_FULL,
} page_loc_t;
#define SMALL_PAGE_V5_UNLINK(h, loc, prev, page) \
do { \
if ((h) && (page)) { \
switch (loc) { \
case LOC_CURRENT: \
(h)->current = NULL; \
break; \
case LOC_PARTIAL: \
if (prev) (prev)->next = (page)->next; \
else (h)->partial_head = (page)->next; \
if ((h)->partial_count > 0) { \
(h)->partial_count--; \
} \
break; \
case LOC_FULL: \
if (prev) (prev)->next = (page)->next; \
else (h)->full_head = (page)->next; \
break; \
default: \
break; \
} \
(page)->next = NULL; \
} \
} while (0)
// ============================================================================
// API
// ============================================================================
SmallHeapCtxV5* small_heap_ctx_v5(void);
// Fast pathPhase v5-1: C6-only route stub, v1/pool fallback
void* small_alloc_fast_v5(size_t size, uint32_t class_idx, SmallHeapCtxV5* ctx);
void small_free_fast_v5(void* ptr, uint32_t class_idx, SmallHeapCtxV5* ctx);
#endif // HAKMEM_SMALLOBJECT_HOTBOX_V5_BOX_H