## Phase POLICY-FAST-PATH-V2 (FROZEN) - Implementation complete: free_policy_fast_v2_box.h + malloc_tiny_fast.h integration - A/B Results: - Mixed (ws=400): -1.6% regression ❌ (branch cost > skip benefit) - C6-heavy (ws=200): +5.4% improvement ✅ - Decision: Default OFF, FROZEN (ws<300 / C6-heavy research only) - Learning: Large WS causes branch misprediction to dominate ## Phase 3-GRADUATE + ENV probe fix - 64-probe retry for getenv() stability during bench_profile putenv() - C6 ULTRA intrusive freelist: FROZEN (research box) ## Phase MID-V35-HOTPATH-OPT-1-DESIGN - Design doc for next optimization target - Target: MID v3.5 alloc/free hot path (C5-C6) - Boxes: Stats Gate, TLS Layout, Boundary Check elimination - Expected: +3-9% on Mixed mainline Files: - core/box/free_policy_fast_v2_box.h (new) - core/box/free_path_stats_box.h/c (policy_fast_v2_skip counter) - core/front/malloc_tiny_fast.h (fast-path integration) - docs/analysis/MID_V35_HOTPATH_OPT_1_DESIGN.md (new) - docs/analysis/PHASE_3_GRADUATE_*.md (new) - CURRENT_TASK.md (phase status update) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
7.6 KiB
7.6 KiB
Phase MID-V35-HOTPATH-OPT-1-DESIGN
目的
Mixed本線(MIXED_TINYV3_C7_SAFE)の alloc側最大ホット(MID v3.5 / C5-C6パス)を最適化する。
背景:
- Phase POLICY-FAST-PATH-V2 で free 側ホットは崩せなかった(大WS時の分岐コスト)
- perf:
tiny_alloc_gate_fastが 19-26% を占める(C6-heavy で顕著) - MID v3.5 は C5/C6 で使用され、Mixed 本線のクリティカルパス
現状分析
small_mid_v35_alloc() のホットパス (core/smallobject_mid_v35.c:71-116)
void* small_mid_v35_alloc(uint32_t class_idx, size_t size) {
(void)size; // ① 未使用パラメータ
if (class_idx < 5 || class_idx > 7) return NULL; // ② 境界チェック
SmallMidV35TlsCtx *ctx = &tls_mid_v35_ctx;
// Fast path
if (ctx->page[class_idx] && ctx->offset[class_idx] < ctx->capacity[class_idx]) {
size_t slot_size = g_slot_sizes[class_idx]; // ③ 配列参照
void *base = (char*)ctx->page[class_idx] + ctx->offset[class_idx] * slot_size;
ctx->offset[class_idx]++;
// ④ Stats更新(必須ではない)
if (ctx->meta[class_idx]) {
ctx->meta[class_idx]->alloc_count++;
}
// ⑤ ヘッダー書き込み
tiny_region_id_write_header(base, class_idx);
return (char*)base + 1;
}
// Slow path: ColdIface refill
...
}
削減可能な work
| # | 箇所 | 現状 | 最適化案 | 期待効果 |
|---|---|---|---|---|
| ① | (void)size |
毎回渡される | size パラメータ削除 | 微小 |
| ② | 境界チェック | 毎回 | caller 側で保証、ここでは削除 | ~1-2 cycles |
| ③ | g_slot_sizes[class_idx] |
配列参照 | TLS ctx に slot_size を持たせる | ~1-2 cycles |
| ④ | alloc_count++ |
毎回 | ENV gate で disable 可能に | ~2-3 cycles |
| ⑤ | ヘッダー書き込み | 毎回必須 | 最適化不可(必須) | - |
small_mid_v35_free() のホットパス (core/smallobject_mid_v35.c:123-160)
void small_mid_v35_free(void *ptr, uint32_t class_idx) {
if (!ptr || class_idx < 5 || class_idx > 7) return; // ① 境界チェック
void *base = (char*)ptr - 1;
// ② page_base 計算(毎回)
size_t page_size = 64 * 1024;
void *page_base = (void*)((uintptr_t)base & ~(page_size - 1));
SmallMidV35TlsCtx *ctx = &tls_mid_v35_ctx;
SmallPageMeta_MID_v3 *meta = ctx->meta[class_idx];
if (meta && meta->ptr == page_base) {
// ③ Stats更新
meta->free_count++;
// ④ Retire チェック
if (meta->free_count >= meta->capacity) {
small_cold_mid_v3_retire_page(meta);
...
}
}
...
}
| # | 箇所 | 現状 | 最適化案 | 期待効果 |
|---|---|---|---|---|
| ① | 境界チェック | 毎回 | caller 側で保証 | ~1-2 cycles |
| ② | page_base 計算 | & ~(64K-1) |
TLS ctx に page_base を持たせる | ~2-3 cycles |
| ③ | free_count++ |
毎回 | ENV gate で disable 可能に | ~2-3 cycles |
| ④ | retire チェック | 毎回分岐 | N 回に1回だけチェック (batch retire) | ~1-2 cycles avg |
箱化計画
Box 1: Stats Gate (削減優先度: 高)
新規ファイル: core/box/mid_v35_stats_gate_box.h
// ENV: HAKMEM_MID_V35_STATS_ENABLED (default 1)
static inline bool mid_v35_stats_enabled(void) {
static int g_enabled = -1;
if (__builtin_expect(g_enabled == -1, 0)) {
const char* e = getenv("HAKMEM_MID_V35_STATS_ENABLED");
g_enabled = (e && *e == '0') ? 0 : 1; // default ON for compatibility
}
return g_enabled;
}
#define MID_V35_STAT_INC(field) \
do { if (__builtin_expect(mid_v35_stats_enabled(), 1)) { (field)++; } } while(0)
適用箇所:
ctx->meta[class_idx]->alloc_count++→MID_V35_STAT_INC(ctx->meta[class_idx]->alloc_count)meta->free_count++→MID_V35_STAT_INC(meta->free_count)
戻しノブ: HAKMEM_MID_V35_STATS_ENABLED=0 で stats 無効化
Box 2: TLS Layout Optimization (削減優先度: 中)
変更ファイル: core/smallobject_mid_v35.c
typedef struct {
void *page[8];
uint32_t offset[8];
uint32_t capacity[8];
SmallPageMeta_MID_v3 *meta[8];
// 追加フィールド
size_t slot_size[8]; // キャッシュ済み slot size
void *page_base[8]; // キャッシュ済み page base (for free comparison)
} SmallMidV35TlsCtx;
効果:
g_slot_sizes[class_idx]配列参照を TLS 読み出しに変更(キャッシュヒット改善)page_base計算を refill 時の1回だけに削減
Box 3: Boundary Check Elimination (削減優先度: 低)
変更ファイル: core/front/malloc_tiny_fast.h
caller 側で class_idx >= 5 && class_idx <= 7 を保証し、small_mid_v35_alloc/free 内のチェックを削除。
リスク: 誤った class_idx で呼ばれた場合のクラッシュ(DEBUG ビルドでは assert 追加)
境界定義
┌─────────────────────────────────────────────────────────────┐
│ malloc_tiny_fast.h │
│ (caller: class_idx 保証、ルーティング決定) │
├─────────────────────────────────────────────────────────────┤
│ smallobject_mid_v35.c │
│ L1 HotBox: TLS fast path (alloc/free) │
│ - Stats Gate (Box 1) で stats 更新を条件付きに │
│ - TLS Layout (Box 2) で配列参照/計算を削減 │
├─────────────────────────────────────────────────────────────┤
│ smallobject_cold_iface_mid_v3.c │
│ L2 ColdIface: refill/retire (変更なし) │
└─────────────────────────────────────────────────────────────┘
戻しノブ一覧
| ENV | Default | 説明 |
|---|---|---|
HAKMEM_MID_V35_STATS_ENABLED |
1 (ON) | 0 で stats 更新を無効化 |
HAKMEM_MID_V35_FAST_TLS |
0 (OFF) | 1 で TLS layout 最適化を有効化 |
実装順序
-
Phase 1 (Box 1): Stats Gate 追加
mid_v35_stats_gate_box.h作成smallobject_mid_v35.cに適用- A/B:
HAKMEM_MID_V35_STATS_ENABLED=0vs=1 - 期待: +2-5% (stats overhead 削除分)
-
Phase 2 (Box 2): TLS Layout 最適化
SmallMidV35TlsCtx拡張- refill 時に slot_size/page_base をキャッシュ
- A/B:
HAKMEM_MID_V35_FAST_TLS=1vs=0 - 期待: +1-3% (配列参照/計算削減分)
-
Phase 3 (Box 3): Boundary Check 削除 (optional)
- DEBUG assert のみ残す
- Release ビルドで無条件削除
- 期待: +0.5-1%
期待効果まとめ
| Box | 対象 | 期待効果 | リスク |
|---|---|---|---|
| Box 1 | Stats Gate | +2-5% | 低 (stats 無効は研究用) |
| Box 2 | TLS Layout | +1-3% | 低 (TLS サイズ増) |
| Box 3 | Boundary Check | +0.5-1% | 中 (誤 class_idx でクラッシュ) |
合計期待: +3-9% (Mixed本線)
次のアクション
- この設計 doc をレビュー
- Phase 1 (Box 1: Stats Gate) を実装
- A/B テストで効果確認
- Phase 2, 3 へ進むか判断