Files
hakmem/core/hakmem_config.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

344 lines
14 KiB
C

// hakmem_config.c - Mode-based Configuration Implementation
#include "hakmem_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hakmem_internal.h" // HAKMEM_LOG for release-silent logging
// ===========================================================================
// Global Configuration Instance
// ===========================================================================
HakemConfig g_hakem_config = {0};
// ===========================================================================
// Mode Names
// ===========================================================================
const char* hak_mode_name(HakemMode mode) {
switch (mode) {
case HAKMEM_MODE_MINIMAL: return "minimal";
case HAKMEM_MODE_FAST: return "fast";
case HAKMEM_MODE_BALANCED: return "balanced";
case HAKMEM_MODE_LEARNING: return "learning";
case HAKMEM_MODE_RESEARCH: return "research";
default: return "unknown";
}
}
// ===========================================================================
// Mode Presets
// ===========================================================================
static void apply_minimal_mode(HakemConfig* cfg) {
cfg->mode = HAKMEM_MODE_MINIMAL;
cfg->mode_name = "minimal";
// Features: ALL OFF (baseline)
cfg->features.alloc = HAKMEM_FEATURE_MALLOC | HAKMEM_FEATURE_MMAP;
cfg->features.cache = 0; // No BigCache
cfg->features.learning = 0; // No ELO/Evolution
cfg->features.memory = 0; // No Batch/THP/FreePo licy
cfg->features.debug = 0; // No debug logging
// Policies
cfg->free_policy = FREE_POLICY_BATCH; // Default (but batch disabled)
cfg->thp_policy = THP_POLICY_OFF;
cfg->evo_phase = EVO_PHASE_FROZEN; // Not used (ELO disabled)
// Parameters
cfg->elo_frozen_strategy = 4; // 2MB threshold (not used)
cfg->batch_threshold = 2097152; // 2MB
// Debug
cfg->verbose = 0;
cfg->ace_trace = 0;
}
static void apply_fast_mode(HakemConfig* cfg) {
cfg->mode = HAKMEM_MODE_FAST;
cfg->mode_name = "fast";
// Features: Pool fast-path + FROZEN learning
cfg->features.alloc = HAKMEM_FEATURE_MALLOC | HAKMEM_FEATURE_MMAP | HAKMEM_FEATURE_POOL;
cfg->features.cache = HAKMEM_FEATURE_BIGCACHE | HAKMEM_FEATURE_TINYPOOL;
cfg->features.learning = HAKMEM_FEATURE_ELO; // FROZEN only
cfg->features.memory = HAKMEM_FEATURE_BATCH_MADVISE | HAKMEM_FEATURE_FREE_POLICY;
cfg->features.debug = 0;
// Policies
cfg->free_policy = FREE_POLICY_ADAPTIVE;
cfg->thp_policy = THP_POLICY_AUTO;
cfg->evo_phase = EVO_PHASE_FROZEN; // FROZEN: no learning overhead
// Parameters
cfg->elo_frozen_strategy = 4; // 2MB threshold (confirmed by learning)
cfg->batch_threshold = 2097152; // 2MB
// Debug
cfg->verbose = 0;
}
static void apply_balanced_mode(HakemConfig* cfg) {
cfg->mode = HAKMEM_MODE_BALANCED;
cfg->mode_name = "balanced";
// Features: L2 Pool + BigCache + ELO FROZEN + Batch (Phase 6.9)
cfg->features.alloc = HAKMEM_FEATURE_MALLOC | HAKMEM_FEATURE_MMAP | HAKMEM_FEATURE_POOL;
cfg->features.cache = HAKMEM_FEATURE_BIGCACHE;
cfg->features.learning = HAKMEM_FEATURE_ELO; // FROZEN only
cfg->features.memory = HAKMEM_FEATURE_BATCH_MADVISE | HAKMEM_FEATURE_FREE_POLICY;
cfg->features.debug = 0;
// Policies
cfg->free_policy = FREE_POLICY_ADAPTIVE;
cfg->thp_policy = THP_POLICY_AUTO;
cfg->evo_phase = EVO_PHASE_FROZEN;
// Parameters
cfg->elo_frozen_strategy = 4; // 2MB threshold
cfg->batch_threshold = 2097152; // 2MB
// Debug
cfg->verbose = 0;
}
static void apply_learning_mode(HakemConfig* cfg) {
cfg->mode = HAKMEM_MODE_LEARNING;
cfg->mode_name = "learning";
// Features: BigCache + ELO LEARN + Batch
cfg->features.alloc = HAKMEM_FEATURE_MALLOC | HAKMEM_FEATURE_MMAP;
cfg->features.cache = HAKMEM_FEATURE_BIGCACHE;
cfg->features.learning = HAKMEM_FEATURE_ELO | HAKMEM_FEATURE_EVOLUTION | HAKMEM_FEATURE_PROFILING;
cfg->features.memory = HAKMEM_FEATURE_BATCH_MADVISE | HAKMEM_FEATURE_FREE_POLICY;
cfg->features.debug = HAKMEM_FEATURE_STATISTICS; // Minimal debug
// Policies
cfg->free_policy = FREE_POLICY_ADAPTIVE;
cfg->thp_policy = THP_POLICY_AUTO;
cfg->evo_phase = EVO_PHASE_LEARN; // LEARN → FROZEN transition
// Parameters
cfg->elo_frozen_strategy = 4; // Initial guess (will be learned)
cfg->batch_threshold = 2097152; // 2MB
// Debug
cfg->verbose = 1; // Minimal logging
}
static void apply_research_mode(HakemConfig* cfg) {
cfg->mode = HAKMEM_MODE_RESEARCH;
cfg->mode_name = "research";
// Features: ALL ON
cfg->features.alloc = HAKMEM_FEATURE_MALLOC | HAKMEM_FEATURE_MMAP;
cfg->features.cache = HAKMEM_FEATURE_BIGCACHE;
cfg->features.learning = HAKMEM_FEATURE_ELO | HAKMEM_FEATURE_EVOLUTION | HAKMEM_FEATURE_PROFILING;
cfg->features.memory = HAKMEM_FEATURE_BATCH_MADVISE | HAKMEM_FEATURE_THP | HAKMEM_FEATURE_FREE_POLICY;
cfg->features.debug = HAKMEM_FEATURE_DEBUG_LOG | HAKMEM_FEATURE_STATISTICS | HAKMEM_FEATURE_TRACE;
// Policies
cfg->free_policy = FREE_POLICY_ADAPTIVE;
cfg->thp_policy = THP_POLICY_ON; // Force THP
cfg->evo_phase = EVO_PHASE_LEARN;
// Parameters
cfg->elo_frozen_strategy = 4;
cfg->batch_threshold = 2097152;
// Debug
cfg->verbose = 2; // Verbose logging
}
void hak_config_apply_mode(HakemMode mode) {
switch (mode) {
case HAKMEM_MODE_MINIMAL: apply_minimal_mode(&g_hakem_config); break;
case HAKMEM_MODE_FAST: apply_fast_mode(&g_hakem_config); break;
case HAKMEM_MODE_BALANCED: apply_balanced_mode(&g_hakem_config); break;
case HAKMEM_MODE_LEARNING: apply_learning_mode(&g_hakem_config); break;
case HAKMEM_MODE_RESEARCH: apply_research_mode(&g_hakem_config); break;
default:
HAKMEM_LOG("Unknown mode %d, using BALANCED\n", mode);
apply_balanced_mode(&g_hakem_config);
break;
}
}
// ===========================================================================
// Environment Variable Parsing
// ===========================================================================
static HakemMode parse_mode_env(const char* mode_str) {
if (!mode_str) return HAKMEM_MODE_BALANCED; // Default
if (strcmp(mode_str, "minimal") == 0) return HAKMEM_MODE_MINIMAL;
if (strcmp(mode_str, "fast") == 0) return HAKMEM_MODE_FAST;
if (strcmp(mode_str, "balanced") == 0) return HAKMEM_MODE_BALANCED;
if (strcmp(mode_str, "learning") == 0) return HAKMEM_MODE_LEARNING;
if (strcmp(mode_str, "research") == 0) return HAKMEM_MODE_RESEARCH;
HAKMEM_LOG("Unknown HAKMEM_MODE='%s', using balanced\n", mode_str);
return HAKMEM_MODE_BALANCED;
}
static void apply_individual_env_overrides(void) {
// Allow individual env vars to override mode presets
const char* free_policy_env = getenv("HAKMEM_FREE_POLICY");
if (free_policy_env) {
if (strcmp(free_policy_env, "batch") == 0) {
g_hakem_config.free_policy = FREE_POLICY_BATCH;
} else if (strcmp(free_policy_env, "keep") == 0) {
g_hakem_config.free_policy = FREE_POLICY_KEEP;
} else if (strcmp(free_policy_env, "adaptive") == 0) {
g_hakem_config.free_policy = FREE_POLICY_ADAPTIVE;
}
}
const char* thp_env = getenv("HAKMEM_THP");
if (thp_env) {
if (strcmp(thp_env, "off") == 0) {
g_hakem_config.thp_policy = THP_POLICY_OFF;
} else if (strcmp(thp_env, "auto") == 0) {
g_hakem_config.thp_policy = THP_POLICY_AUTO;
} else if (strcmp(thp_env, "on") == 0) {
g_hakem_config.thp_policy = THP_POLICY_ON;
}
}
const char* verbose_env = getenv("HAKMEM_VERBOSE");
if (verbose_env) {
g_hakem_config.verbose = atoi(verbose_env);
}
const char* ace_trace_env = getenv("HAKMEM_ACE_TRACE");
if (ace_trace_env) {
g_hakem_config.ace_trace = atoi(ace_trace_env);
}
// Individual feature toggles (override mode presets)
const char* disable_bigcache = getenv("HAKMEM_DISABLE_BIGCACHE");
if (disable_bigcache && atoi(disable_bigcache)) {
g_hakem_config.features.cache &= ~HAKMEM_FEATURE_BIGCACHE;
}
const char* disable_elo = getenv("HAKMEM_DISABLE_ELO");
if (disable_elo && atoi(disable_elo)) {
g_hakem_config.features.learning &= ~HAKMEM_FEATURE_ELO;
}
const char* disable_batch = getenv("HAKMEM_DISABLE_BATCH");
if (disable_batch && atoi(disable_batch)) {
g_hakem_config.features.memory &= ~HAKMEM_FEATURE_BATCH_MADVISE;
}
}
void hak_config_init(void) {
// Step 1: Check HAKMEM_MODE (highest priority)
const char* mode_env = getenv("HAKMEM_MODE");
HakemMode mode = parse_mode_env(mode_env);
hak_config_apply_mode(mode);
// Step 2: Apply individual env var overrides
apply_individual_env_overrides();
// Step 3: Print configuration (if verbose)
if (g_hakem_config.verbose >= 1) {
hak_config_print();
}
}
// ===========================================================================
// Debug Printing
// ===========================================================================
void hak_config_print(void) {
HAKMEM_LOG("\n========================================\n");
HAKMEM_LOG("hakmem Configuration\n");
HAKMEM_LOG("========================================\n");
HAKMEM_LOG("Mode: %s\n", g_hakem_config.mode_name);
HAKMEM_LOG("\n");
HAKMEM_LOG("Features:\n");
HAKMEM_LOG(" Allocation:\n");
HAKMEM_LOG(" malloc: %s\n", (g_hakem_config.features.alloc & HAKMEM_FEATURE_MALLOC) ? "ON" : "OFF");
HAKMEM_LOG(" mmap: %s\n", (g_hakem_config.features.alloc & HAKMEM_FEATURE_MMAP) ? "ON" : "OFF");
HAKMEM_LOG(" pool: %s\n", (g_hakem_config.features.alloc & HAKMEM_FEATURE_POOL) ? "ON" : "OFF");
HAKMEM_LOG(" Caching:\n");
HAKMEM_LOG(" BigCache: %s\n", (g_hakem_config.features.cache & HAKMEM_FEATURE_BIGCACHE) ? "ON" : "OFF");
HAKMEM_LOG(" TinyPool: %s\n", (g_hakem_config.features.cache & HAKMEM_FEATURE_TINYPOOL) ? "ON" : "OFF");
HAKMEM_LOG(" Learning:\n");
HAKMEM_LOG(" ELO: %s\n", (g_hakem_config.features.learning & HAKMEM_FEATURE_ELO) ? "ON" : "OFF");
HAKMEM_LOG(" Evolution: %s\n", (g_hakem_config.features.learning & HAKMEM_FEATURE_EVOLUTION) ? "ON" : "OFF");
HAKMEM_LOG(" Profiling: %s\n", (g_hakem_config.features.learning & HAKMEM_FEATURE_PROFILING) ? "ON" : "OFF");
HAKMEM_LOG(" Memory:\n");
HAKMEM_LOG(" Batch madvise: %s\n", (g_hakem_config.features.memory & HAKMEM_FEATURE_BATCH_MADVISE) ? "ON" : "OFF");
HAKMEM_LOG(" THP: %s\n", (g_hakem_config.features.memory & HAKMEM_FEATURE_THP) ? "ON" : "OFF");
HAKMEM_LOG(" Free policy: %s\n", (g_hakem_config.features.memory & HAKMEM_FEATURE_FREE_POLICY) ? "ON" : "OFF");
HAKMEM_LOG(" Debug:\n");
HAKMEM_LOG(" Logging: %s\n", (g_hakem_config.features.debug & HAKMEM_FEATURE_DEBUG_LOG) ? "ON" : "OFF");
HAKMEM_LOG(" Statistics: %s\n", (g_hakem_config.features.debug & HAKMEM_FEATURE_STATISTICS) ? "ON" : "OFF");
HAKMEM_LOG(" Trace: %s\n", (g_hakem_config.features.debug & HAKMEM_FEATURE_TRACE) ? "ON" : "OFF");
HAKMEM_LOG(" ACE Trace: %s\n", g_hakem_config.ace_trace ? "ON" : "OFF");
HAKMEM_LOG("\n");
HAKMEM_LOG("Policies:\n");
HAKMEM_LOG(" Free policy: %s\n",
g_hakem_config.free_policy == FREE_POLICY_BATCH ? "batch" :
g_hakem_config.free_policy == FREE_POLICY_KEEP ? "keep" :
g_hakem_config.free_policy == FREE_POLICY_ADAPTIVE ? "adaptive" : "unknown");
HAKMEM_LOG(" THP policy: %s\n",
g_hakem_config.thp_policy == THP_POLICY_OFF ? "off" :
g_hakem_config.thp_policy == THP_POLICY_AUTO ? "auto" :
g_hakem_config.thp_policy == THP_POLICY_ON ? "on" : "unknown");
HAKMEM_LOG(" Evo phase: %s\n",
g_hakem_config.evo_phase == EVO_PHASE_LEARN ? "learn" :
g_hakem_config.evo_phase == EVO_PHASE_FROZEN ? "frozen" :
g_hakem_config.evo_phase == EVO_PHASE_CANARY ? "canary" : "unknown");
HAKMEM_LOG("\n");
HAKMEM_LOG("Parameters:\n");
HAKMEM_LOG(" ELO frozen strategy: %d\n", g_hakem_config.elo_frozen_strategy);
HAKMEM_LOG(" Batch threshold: %zu bytes\n", g_hakem_config.batch_threshold);
HAKMEM_LOG(" Verbose level: %d\n", g_hakem_config.verbose);
HAKMEM_LOG("========================================\n\n");
}
// ===========================================================================
// Feature Helper (for hakmem_features.h)
// ===========================================================================
HakemFeatureSet hak_features_for_mode(const char* mode_str) {
HakemMode mode = parse_mode_env(mode_str);
HakemConfig temp_cfg;
memset(&temp_cfg, 0, sizeof(temp_cfg));
switch (mode) {
case HAKMEM_MODE_MINIMAL: apply_minimal_mode(&temp_cfg); break;
case HAKMEM_MODE_FAST: apply_fast_mode(&temp_cfg); break;
case HAKMEM_MODE_BALANCED: apply_balanced_mode(&temp_cfg); break;
case HAKMEM_MODE_LEARNING: apply_learning_mode(&temp_cfg); break;
case HAKMEM_MODE_RESEARCH: apply_research_mode(&temp_cfg); break;
default: apply_balanced_mode(&temp_cfg); break;
}
return temp_cfg.features;
}
void hak_features_print(HakemFeatureSet* fs) {
(void)fs;
HAKMEM_LOG("Feature Set:\n");
HAKMEM_LOG(" alloc: 0x%08x\n", fs->alloc);
HAKMEM_LOG(" cache: 0x%08x\n", fs->cache);
HAKMEM_LOG(" learning: 0x%08x\n", fs->learning);
HAKMEM_LOG(" memory: 0x%08x\n", fs->memory);
HAKMEM_LOG(" debug: 0x%08x\n", fs->debug);
}
// Box Refactor line default: enable SuperSlab unless explicitly disabled by env or diet mode
int g_use_superslab = 1;