Phase 3 C1: TLS Prefetch Implementation - NEUTRAL Result (Research Box)

Step 1 & 2 Complete:
- Implemented: core/front/malloc_tiny_fast.h prefetch (lines 264-267, 331-334)
  - LEGACY path prefetch of g_unified_cache[class_idx] to L1
  - ENV gate: HAKMEM_TINY_PREFETCH=0/1 (default OFF)
  - Conditional: only when prefetch enabled + route_kind == LEGACY

- A/B test (Mixed 10-run): PREFETCH=0 (39.33M) → =1 (39.20M) = -0.34% avg
  - Median: +1.28% (within ±1.0% neutral range)
  - Result: 🔬 NEUTRAL (research box, default OFF)

Decision: FREEZE as research box
- Average -0.34% suggests prefetch overhead > benefit
- Prefetch timing too late (after route_kind selection)
- TLS cache access is already fast (head/tail indices)
- Actual memory wait happens at slots[] array access (after prefetch)

Technical Learning:
- Prefetch effectiveness depends on L1 miss rate at access time
- Inserting prefetch after route selection may be too late
- Future approach: move prefetch earlier or use different target

Next: Phase 3 C2 (Metadata Cache Optimization, expected +5-10%)

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-13 19:01:57 +09:00
parent d54893ea1d
commit d0b931b197
6 changed files with 115 additions and 6 deletions

View File

@ -170,10 +170,32 @@
- C3 (Static routing): +2.20%
- **Total: ~6.8%** (baseline 35.2M → ~39.8M ops/s)
**優先度 C1** - TLS cache prefetch:
- `__builtin_prefetch(g_small_policy_v7, 0, 3)` on malloc entry
- Improve L1 hit rate on cold start
- Expected: +2-4%
#### Phase 3 C1: TLS Cache Prefetch 🔬 NEUTRAL / FREEZE
**設計メモ**: `docs/analysis/PHASE3_C1_TLS_PREFETCH_1_DESIGN.md`
**狙い**: malloc ホットパス LEGACY 入口で `g_unified_cache[class_idx]` を L1 prefetch数十クロック早期
**実装完了** ✅:
- `core/front/malloc_tiny_fast.h` (lines 264-267, 331-334)
- env_cfg->alloc_route_shape=1 の fast path線264-267
- env_cfg->alloc_route_shape=0 の fallback path線331-334
- ENV gate: `HAKMEM_TINY_PREFETCH=0/1`default 0
**A/B テスト結果** 🔬 NEUTRAL:
- Mixed (10-run): 39,335,109 → 39,203,334 ops/s (**-0.34% average**, median **+1.28%**)
- Average gain: -0.34%わずかな回帰、±1.0% 範囲内)
- Median gain: +1.28%(閾値超え)
- **Decision: NEUTRAL** (研究箱維持、デフォルト OFF
- 理由: Average で -0.34% なので、prefetch 効果が噪音範囲
- Prefetch は "当たるかどうか" が不確定TLS access timing dependent
- ホットパス後tiny_hot_alloc_fast 直前)での実行では効果限定的
**技術考察**:
- prefetch が効果を発揮するには、L1 miss が発生する必要がある
- TLS キャッシュは unified_cache_pop() で素早くアクセスhead/tail インデックス)
- 実際のメモリ待ちは slots[] 配列へのアクセス時prefetch より後)
- 改善案: prefetch をもっと早期route_kind 決定前)に移動するか、形状を変更
**優先度 C2** - Slab metadata cache optimization:
- Profile cache-miss hotspots (policy struct, slab metadata)

View File

@ -261,6 +261,10 @@ static inline void* malloc_tiny_fast_for_class(size_t size, int class_idx) {
if (TINY_HOT_LIKELY(env_cfg->alloc_route_shape)) {
// B3 optimized: Prioritize LEGACY with LIKELY hint
if (TINY_HOT_LIKELY(route_kind == SMALL_ROUTE_LEGACY)) {
// Phase 3 C1: TLS cache prefetch (prefetch g_unified_cache[class_idx] to L1)
if (__builtin_expect(env_cfg->tiny_prefetch, 0)) {
__builtin_prefetch(&g_unified_cache[class_idx], 0, 3);
}
// LEGACY fast path: Unified Cache hot/cold
void* ptr = tiny_hot_alloc_fast(class_idx);
if (TINY_HOT_LIKELY(ptr != NULL)) {
@ -324,6 +328,10 @@ static inline void* malloc_tiny_fast_for_class(size_t size, int class_idx) {
break;
}
// Phase 3 C1: TLS cache prefetch (prefetch g_unified_cache[class_idx] to L1)
if (__builtin_expect(env_cfg->tiny_prefetch, 0)) {
__builtin_prefetch(&g_unified_cache[class_idx], 0, 3);
}
// LEGACY fallback: Unified Cache hot/cold path
void* ptr = tiny_hot_alloc_fast(class_idx);
if (TINY_HOT_LIKELY(ptr != NULL)) {

View File

@ -40,6 +40,7 @@ HAKMEM_BENCH_MAX_SIZE=1024
- `HAKMEM_FREE_TINY_FAST_HOTCOLD=1`Phase FREE-TINY-FAST-DUALHOT-1: free の第2ホット(C0-C3)を直行)
- `HAKMEM_WRAP_SHAPE=1`Phase 2 B4: wrapper hot/cold split を default ON
- `HAKMEM_TINY_ALLOC_ROUTE_SHAPE=1`Phase 2 B3: alloc の route dispatch 形を最適化)
- `HAKMEM_TINY_STATIC_ROUTE=1`Phase 3 C3: policy_snapshot bypass を default ON
- `HAKMEM_MID_V3_ENABLED=1`Phase MID-V3: 257-768B, C6 only
- `HAKMEM_MID_V3_CLASSES=0x40`C6 only, C7 は ULTRA に任せる)
- `HAKMEM_MID_V35_ENABLED=0`Phase v11a-5: Mixed では MID v3.5 OFF が最速)

View File

@ -0,0 +1,69 @@
# Phase 3 C1: TLS PrefetchTiny alloc hot path設計メモ
## 目的
Phase 2-3B3/B4/C3で「形分岐・I-cache」は勝ち形に寄った。
次は **L1D miss / pointer chase** を減らすための “軽い prefetch” を A/B する。
対象は policy ではなく、実際の alloc が触る **TLS cache**:
- `TinyUnifiedCache g_unified_cache[class]``core/front/tiny_unified_cache.h`
- 必要なら `cache->slots[]` の先頭付近head/tail 周辺)
## 非目標
- ルーティングやアルゴリズム変更はしないprefetch は “ヒント” のみ)
- 常時ログは禁止(必要なら `HAKMEM_DEBUG_COUNTERS` のみ)
- “当たり前に速い” ことは期待しないNO-GO なら即 freeze
## Box Theory箱割り
### L0: Env戻せる
- 既存 ENV を使用: `HAKMEM_TINY_PREFETCH=0/1`default 0
- 目的: prefetch の on/off を即切替(回帰時に即戻せる)
### L1: PrefetchBox境界: 1 箇所)
責務: **malloc の hot path で 1 回だけ** prefetch を実行する。
実装場所は “入口” に固定(`malloc_tiny_fast_for_class()`)。
候補 APIheader-only で OK:
- `tiny_alloc_prefetch_tls_cache(class_idx, route_kind)`
- `route_kind == SMALL_ROUTE_LEGACY` のときだけ `g_unified_cache[class_idx]` を prefetch
- 余計な prefetch を避けるC6=MID 等で無駄撃ちしない)
## 実装指示(小パッチ順)
1. **Prefetch 実装(最小)**
- 追加箇所: `core/front/malloc_tiny_fast.h``malloc_tiny_fast_for_class()`
- 条件:
- `tiny_env_cfg()->tiny_prefetch == 1`
- `route_kind == SMALL_ROUTE_LEGACY`
- 実行:
- `__builtin_prefetch(&g_unified_cache[class_idx], 0, 3);`
- 注意:
- `g_unified_cache` は TLS なので “当たる” 前提で入れすぎない1 回だけ)
2. **Optional勝ち筋が見えたら**
- `TinyUnifiedCache* cache = &g_unified_cache[class_idx];`
- `if (cache->slots) __builtin_prefetch(&cache->slots[cache->head], 0, 3);`
- ※ ただしロードが増えるので、まずは 1. の最小で A/B
3. **ドキュメント**
- `docs/specs/ENV_VARS_COMPLETE.md``HAKMEM_TINY_PREFETCH` を追記
- `docs/analysis/PHASE3_CACHE_LOCALITY_NEXT_INSTRUCTIONS.md` の C1 をこの設計に合わせて更新
## A/BGO/NO-GO
- Mixed`HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE`10-run
- 比較: `HAKMEM_TINY_PREFETCH=0` vs `=1`
- **GO**: +1.0% 以上
- **NO-GO**: -1.0% 以下 → freeze
- ±1% は “研究箱維持”デフォルトOFFのまま
## 期待値の現実
prefetch は “刺さるときだけ刺さる”。
勝ち筋は「route 形の整理B3/B4/C3で instruction が減った結果、メモリ待ちが相対的に目立つ」状態になっていること。
もし勝てないなら、次は C2metadata localityへ進む。

View File

@ -49,11 +49,14 @@
### C1優先度: 🟡 中): TLS Cache Prefetch
**狙い**: policy_snapshot 実行前に g_small_policy_v7 をプリフェッチ
**狙い**: policy ではなく、実際に alloc が触る **TLS cache**Unified Cacheをプリフェッチ
**設計メモ**: `docs/analysis/PHASE3_C1_TLS_PREFETCH_1_DESIGN.md`
**実装**:
```c
__builtin_prefetch(g_small_policy_v7, 0, 3); // read intent (prefetch for load)
// malloc_tiny_fast_for_class() 内で、LEGACY route のときだけ:
__builtin_prefetch(&g_unified_cache[class_idx], 0, 3);
```
**期待**: +2-4%

View File

@ -96,6 +96,12 @@ From `/mnt/workdisk/public_share/hakmem/core/hakmem_tiny_stats.h`:
- **Impact**: A/B gate for policy snapshot cost removal (research box until GO)
- **Notes**: v7 learner が有効な場合(`HAKMEM_SMALL_HEAP_V7_ENABLED=1` かつ learner 無効化なし)は安全のため強制 OFF
#### HAKMEM_TINY_PREFETCH
- **Default**: 0 (disabled)
- **Purpose**: Prefetch hints for Tiny hot paths (Phase 3 C1)
- **Impact**: `malloc_tiny_fast_for_class()` の LEGACY route で TLS Unified Cache を `__builtin_prefetch()` する A/B gate
- **Notes**: Prefetch は workload 依存。NO-GO なら即 freezedefault OFF のまま)
---
### 2. Tiny Pool TLS Caching (Performance Critical)