Files
hakmem/core/box/smallobject_hotbox_v5_box.h
Moe Charm (CI) 2a548875b8 Phase v5-4: Header light mode & freelist optimization
Implements header write optimization for C6 v5 allocator by moving
header initialization from per-alloc time to carve time (during page
refill). This eliminates redundant header writes on the hot path.

Implementation:
- Added HAKMEM_SMALL_HEAP_V5_HEADER_MODE ENV (full|light, default: full)
- Added header_mode field to SmallHeapCtxV5 (cached per-thread)
- Modified alloc fast/slow paths to skip header write in light mode
- Modified refill to write headers during carve in light mode
- Free path unchanged (header validation still works)

Benchmark Results (2M iterations, ws=400):

C6-HEAVY (257-768B):
- Baseline (v5 OFF): 47.95 Mops/s
- v5 full mode:       38.97 Mops/s (-18.7% vs baseline)
- v5 light mode:      39.25 Mops/s (-18.1% vs baseline, +0.7% vs full)

MIXED 16-1024B:
- v5 OFF:       43.59 Mops/s
- v5 full mode: 36.53 Mops/s (-16.2% vs OFF)
- v5 light mode: 38.04 Mops/s (-12.7% vs OFF, +4.1% vs full)

Analysis:
- Light mode shows modest improvement over full (+0.7-4.1%)
- C6 v5 performance gap vs baseline (-18%) indicates need for
  further optimization beyond header writes
- Mixed workload benefits more from light mode (+4.1% vs full)
- No regressions in safety/correctness observed

Research findings:
- Header write optimization alone insufficient to close v5 gap
- Need to investigate other hot path costs (freelist ops, metadata access)
- Light mode validates the carve-time header concept

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-11 05:12:39 +09:00

135 lines
4.8 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>
#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;
// 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)
} 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