Files
hakmem/core/box/capacity_box.c
Moe Charm (CI) acc64f2438 Phase ML1: Pool v1 memset 89.73% overhead 軽量化 (+15.34% improvement)
## Summary
- ChatGPT により bench_profile.h の setenv segfault を修正(RTLD_NEXT 経由に切り替え)
- core/box/pool_zero_mode_box.h 新設:ENV キャッシュ経由で ZERO_MODE を統一管理
- core/hakmem_pool.c で zero mode に応じた memset 制御(FULL/header/off)
- A/B テスト結果:ZERO_MODE=header で +15.34% improvement(1M iterations, C6-heavy)

## Files Modified
- core/box/pool_api.inc.h: pool_zero_mode_box.h include
- core/bench_profile.h: glibc setenv → malloc+putenv(segfault 回避)
- core/hakmem_pool.c: zero mode 参照・制御ロジック
- core/box/pool_zero_mode_box.h (新設): enum/getter
- CURRENT_TASK.md: Phase ML1 結果記載

## Test Results
| Iterations | ZERO_MODE=full | ZERO_MODE=header | Improvement |
|-----------|----------------|-----------------|------------|
| 10K       | 3.06 M ops/s   | 3.17 M ops/s    | +3.65%     |
| 1M        | 23.71 M ops/s  | 27.34 M ops/s   | **+15.34%** |

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-10 09:08:18 +09:00

116 lines
3.6 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.

// capacity_box.c - Box Capacity Manager Implementation
#include "capacity_box.h"
#include "../tiny_adaptive_sizing.h" // TLSCacheStats, adaptive_sizing_init()
#include "../hakmem_tiny.h" // g_tls_sll_count
#include "../hakmem_tiny_config.h" // TINY_NUM_CLASSES, TINY_TLS_MAG_CAP
#include "../hakmem_tiny_integrity.h" // HAK_CHECK_CLASS_IDX
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
// ============================================================================
// Internal State
// ============================================================================
// Initialization flag (atomic for thread-safety)
static _Atomic int g_box_cap_initialized = 0;
// External declarations (from adaptive_sizing and hakmem_tiny)
extern __thread TLSCacheStats g_tls_cache_stats[TINY_NUM_CLASSES]; // TLS variable!
extern __thread TinyTLSSLL g_tls_sll[TINY_NUM_CLASSES];
extern int g_sll_multiplier;
// ============================================================================
// Box Capacity API Implementation
// ============================================================================
void box_cap_init(void) {
// Idempotent: only initialize once
int expected = 0;
if (atomic_compare_exchange_strong(&g_box_cap_initialized, &expected, 1)) {
// First call: initialize adaptive sizing
adaptive_sizing_init();
}
// Already initialized or just initialized: safe to proceed
}
bool box_cap_is_initialized(void) {
return atomic_load(&g_box_cap_initialized) != 0;
}
uint32_t box_cap_get(int class_idx) {
// PRIORITY 1: Bounds check
HAK_CHECK_CLASS_IDX(class_idx, "box_cap_get");
// Ensure initialized
if (!box_cap_is_initialized()) {
// Auto-initialize on first use (defensive)
box_cap_init();
}
// Compute SLL capacity using same logic as sll_cap_for_class()
// This centralizes the capacity calculation旧 g_sll_cap_override は削除済み)。
// Get base capacity from adaptive sizing
uint32_t cap = g_tls_cache_stats[class_idx].capacity;
// Apply class-specific multipliers
if (class_idx <= 3) {
// Hot classes: multiply by g_sll_multiplier
uint32_t mult = (g_sll_multiplier > 0 ? (uint32_t)g_sll_multiplier : 1u);
uint64_t want = (uint64_t)cap * (uint64_t)mult;
if (want > (uint64_t)TINY_TLS_MAG_CAP) {
cap = TINY_TLS_MAG_CAP;
} else {
cap = (uint32_t)want;
}
} else if (class_idx >= 4) {
// Mid-large classes: halve capacity
cap = (cap > 1u ? (cap / 2u) : 1u);
}
return cap;
}
bool box_cap_has_room(int class_idx, uint32_t n) {
// PRIORITY 1: Bounds check
HAK_CHECK_CLASS_IDX(class_idx, "box_cap_has_room");
uint32_t cap = box_cap_get(class_idx);
uint32_t used = g_tls_sll[class_idx].count;
// Check if adding N would exceed capacity
if (used >= cap) return false;
uint32_t avail = cap - used;
return (n <= avail);
}
uint32_t box_cap_avail(int class_idx) {
// PRIORITY 1: Bounds check
HAK_CHECK_CLASS_IDX(class_idx, "box_cap_avail");
uint32_t cap = box_cap_get(class_idx);
uint32_t used = g_tls_sll[class_idx].count;
if (used >= cap) return 0;
return (cap - used);
}
void box_cap_update(int class_idx, uint32_t new_cap) {
// PRIORITY 1: Bounds check
HAK_CHECK_CLASS_IDX(class_idx, "box_cap_update");
// Ensure initialized
if (!box_cap_is_initialized()) {
box_cap_init();
}
// Clamp to max
if (new_cap > TINY_TLS_MAG_CAP) {
new_cap = TINY_TLS_MAG_CAP;
}
// Update adaptive sizing stats
g_tls_cache_stats[class_idx].capacity = new_cap;
}