Files
hakmem/core/box/smallobject_v5_env_box.h
Moe Charm (CI) 2f5d53fd6d Phase v5-5: TLS cache for C6 v5
Add 1-slot TLS cache to C6 v5 to reduce page_meta access overhead.

Implementation:
- Add HAKMEM_SMALL_HEAP_V5_TLS_CACHE_ENABLED ENV (default: 0)
- SmallHeapCtxV5: add c6_cached_block field for TLS cache
- alloc: cache hit bypasses page_meta lookup, returns immediately
- free: empty cache stores block, full cache evicts old block first

Results (1M iter, ws=400, HEADER_MODE=full):
- C6-heavy (257-768B): 35.53M → 37.02M ops/s (+4.2%)
- Mixed 16-1024B: 38.04M → 37.93M ops/s (-0.3%, noise)

Known issue: header_mode=light has infinite loop bug
(freelist pointer/header collision). Full mode only for now.

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

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

158 lines
5.5 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_v5_env_box.h - SmallObject v5 環境ゲートPhase v5-0
//
// ENV ベース: HAKMEM_SMALL_HEAP_V5_ENABLED, HAKMEM_SMALL_HEAP_V5_CLASSES
#ifndef HAKMEM_SMALLOBJECT_V5_ENV_BOX_H
#define HAKMEM_SMALLOBJECT_V5_ENV_BOX_H
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
// ENV sentinel values
#define ENV_UNINIT (-1)
#define ENV_ENABLED (1)
#define ENV_DISABLED (0)
// route priority enum
enum small_route_priority {
ROUTE_PRIORITY_V4 = 0,
ROUTE_PRIORITY_V5 = 1,
ROUTE_PRIORITY_AUTO = 2,
};
// small_heap_v5_enabled() - グローバル v5 enable check
static inline int small_heap_v5_enabled(void) {
static int g_enabled = ENV_UNINIT;
if (__builtin_expect(g_enabled == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V5_ENABLED");
g_enabled = (e && *e && *e != '0') ? ENV_ENABLED : ENV_DISABLED;
}
return (g_enabled == ENV_ENABLED);
}
// small_heap_v5_class_mask() - v5 対象クラスのビットマスク
static inline uint32_t small_heap_v5_class_mask(void) {
static int g_mask = ENV_UNINIT; // sentinel
if (__builtin_expect(g_mask == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V5_CLASSES");
if (e && *e) {
g_mask = (int)strtoul(e, NULL, 0);
} else {
g_mask = 0x0; // default: OFF
}
}
return (uint32_t)g_mask;
}
// small_heap_v5_class_enabled() - 指定クラスが v5 有効か
static inline int small_heap_v5_class_enabled(uint32_t class_idx) {
if (class_idx >= 8) return 0;
if (!small_heap_v5_enabled()) return 0;
uint32_t mask = small_heap_v5_class_mask();
return (mask & (1u << class_idx)) ? 1 : 0;
}
// 便利関数
static inline int small_heap_v5_c6_enabled(void) {
return small_heap_v5_class_enabled(6);
}
static inline int small_heap_v5_c5_enabled(void) {
return small_heap_v5_class_enabled(5);
}
static inline int small_heap_v5_c7_enabled(void) {
return small_heap_v5_class_enabled(7);
}
// small_route_priority() - route priority (v4/v5/auto)
// ENV: HAKMEM_ROUTE_PRIORITY={v4|v5|auto}, default: v4
static inline int small_route_priority(void) {
static int g_priority = ENV_UNINIT;
if (__builtin_expect(g_priority == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_ROUTE_PRIORITY");
if (e && *e) {
if (strcmp(e, "v5") == 0) {
g_priority = ROUTE_PRIORITY_V5;
} else if (strcmp(e, "auto") == 0) {
g_priority = ROUTE_PRIORITY_AUTO;
} else {
g_priority = ROUTE_PRIORITY_V4; // default or "v4"
}
} else {
g_priority = ROUTE_PRIORITY_V4; // default
}
}
return g_priority;
}
// small_heap_v5_segment_size() - segment size override
// ENV: HAKMEM_SMALL_HEAP_V5_SEGMENT_SIZE, default: 2MiB (2*1024*1024)
static inline size_t small_heap_v5_segment_size(void) {
static int g_size = ENV_UNINIT;
if (__builtin_expect(g_size == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V5_SEGMENT_SIZE");
if (e && *e) {
size_t sz = (size_t)strtoul(e, NULL, 0);
// validate: must be power of 2, >= 64KiB
if (sz >= (64 * 1024) && (sz & (sz - 1)) == 0) {
g_size = (int)sz;
} else {
g_size = (2 * 1024 * 1024); // fallback to default
}
} else {
g_size = (2 * 1024 * 1024); // default: 2MiB
}
}
return (size_t)g_size;
}
// ============================================================================
// Phase v5-4: Header mode configuration
// ============================================================================
// Header mode enum
#define SMALL_HEAP_V5_HEADER_MODE_FULL 0
#define SMALL_HEAP_V5_HEADER_MODE_LIGHT 1
// small_heap_v5_header_mode() - header write mode (default: full)
// ENV: HAKMEM_SMALL_HEAP_V5_HEADER_MODE={full|light}, default: full
// - full: write header on every alloc (safe, standard)
// - light: write header once during carve, skip on alloc (research mode, +2-4% perf)
static inline int small_heap_v5_header_mode(void) {
static int g_header_mode = ENV_UNINIT;
if (__builtin_expect(g_header_mode == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V5_HEADER_MODE");
if (e && *e) {
if (strcmp(e, "light") == 0 || strcmp(e, "LIGHT") == 0 || *e == '1') {
g_header_mode = SMALL_HEAP_V5_HEADER_MODE_LIGHT;
} else {
g_header_mode = SMALL_HEAP_V5_HEADER_MODE_FULL; // default or "full"
}
} else {
g_header_mode = SMALL_HEAP_V5_HEADER_MODE_FULL; // default: full
}
}
return g_header_mode;
}
// ============================================================================
// Phase v5-5: TLS cache configuration (research mode)
// ============================================================================
// small_heap_v5_tls_cache_enabled() - TLS cache enable check (default: disabled)
// ENV: HAKMEM_SMALL_HEAP_V5_TLS_CACHE_ENABLED={0|1}, default: 0
// - 0: disabled (standard behavior)
// - 1: enabled (C6 TLS cache, +1-2% perf, research mode)
static inline int small_heap_v5_tls_cache_enabled(void) {
static int g_tls_cache_enabled = ENV_UNINIT;
if (__builtin_expect(g_tls_cache_enabled == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V5_TLS_CACHE_ENABLED");
g_tls_cache_enabled = (e && *e && *e != '0') ? ENV_ENABLED : ENV_DISABLED;
}
return (g_tls_cache_enabled == ENV_ENABLED);
}
#endif // HAKMEM_SMALLOBJECT_V5_ENV_BOX_H