Files
hakmem/docs/analysis/PHASE14_POINTER_CHASE_REDUCTION_1_DESIGN.md
Moe Charm (CI) f8fb05bc13 Phase 14 v1: Pointer-Chase Reduction (tcache) NEUTRAL (+0.20%)
Implementation:
- Intrusive LIFO tcache layer (L1) before UnifiedCache
- TLS per-class bins (head pointer + count)
- Intrusive next pointers (via tiny_next_store/load SSOT)
- Cap: 64 blocks per class (default)
- ENV: HAKMEM_TINY_TCACHE=0/1 (default: 0, OFF)

A/B Test Results (Mixed 10-run):
- Baseline (TCACHE=0): 51,083,379 ops/s
- Optimized (TCACHE=1): 51,186,838 ops/s
- Mean delta: +0.20% (below +1.0% GO threshold)
- Median delta: +0.59%

Verdict: NEUTRAL - Freeze as research box (default OFF)

Root Cause (v1 wiring incomplete):
- Free side pushes to tcache via unified_cache_push()
- Alloc hot path (tiny_hot_alloc_fast) doesn't consume tcache
- tcache becomes "sink" without alloc-side pop → ROI not measurable

Files:
- Created: core/box/tiny_tcache_{env_box,box}.h, tiny_tcache_env_box.c
- Modified: core/front/tiny_unified_cache.h (integration)
- Modified: core/bench_profile.h (refresh sync)
- Modified: Makefile (build integration)
- Results: docs/analysis/PHASE14_POINTER_CHASE_REDUCTION_1_AB_TEST_RESULTS.md
- v2 Instructions: docs/analysis/PHASE14_POINTER_CHASE_REDUCTION_2_NEXT_INSTRUCTIONS.md

Next: Phase 14 v2 (connect tcache to tiny_front_hot_box alloc/free hot path)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 01:28:50 +09:00

5.7 KiB
Raw Blame History

Phase 14: Pointer-Chase Reduction v1Tiny tcache-style intrusive LIFO

Date: 2025-12-14
Status: DESIGNPhase 14 kickoff


0. Executive Summary1枚

Phase 12 の gap 仮説のうち:

  • Header write tax → Phase 13 v1 / E5-2 の範囲では NEUTRAL(決定打にならない)

次の高 ROI 候補は thread cache / pointer-chase / “tcache 相当の構造差”

現状の Tiny frontend は TinyUnifiedCache(配列 + head/tail の FIFOを多用しており、

  • pointer indirectioncache->slots 参照)
  • FIFO による “古いブロック再利用”(局所性低下)
  • 操作あたりの命令数full/empty 判定 + index 更新)

が system mallocglibc tcache: intrusive LIFOに比べて不利になり得る。

Phase 14 v1 は Box Theory を維持したまま、TinyUnifiedCache の前段に “intrusive LIFO tcache” を 1 層追加する:

  • hit 時: head pointer + block 内 next だけで完結(配列アクセス無し)
  • miss / overflow 時: 既存の UnifiedCache配列へフォールバック境界 1 箇所)

1. 現状why

1.1 現行の主要ホット

Phase 10 以降の統合で front_fastlane_try_free が集約点になっているconsolidation 成功)。 その中で “legacy fallback” が unified_cache_push/pop に寄るため、TinyUnifiedCache の形状が ROI に直結する。

1.2 UnifiedCache の現行形状

  • core/front/tiny_unified_cache.h:
    • slots(ヒープ確保配列)+ head/tailFIFO
    • push/pop で配列アクセスが必ず発生

対して glibc tcache は:

  • per-bin head pointerintrusive LIFO
  • small count上限だけ

2. 提案Phase 14 v1

2.1 追加する箱Box Theory

L0: tiny_tcache_env_box          (ENV gate, refresh, rollback)
  ↓
L1: tiny_tcache_box              (intrusive LIFO: push/pop, cap, minimal stats)
  ↓
L2: tiny_unified_cache_box        (既存: array cache)

境界は 1 箇所:

  • tiny_tcache_try_*() が fail したら 既存 unified_cache_*() に落とすだけ

2.2 API最小

// core/box/tiny_tcache_env_box.h
int tiny_tcache_enabled(void);              // ENV: HAKMEM_TINY_TCACHE=0/1 (default 0)
uint16_t tiny_tcache_cap(void);             // ENV: HAKMEM_TINY_TCACHE_CAP (default 64, pow2不要)
void tiny_tcache_env_refresh_from_env(void);// bench_profile putenv 同期用

// core/box/tiny_tcache_box.h
bool tiny_tcache_try_push(int class_idx, void* base); // handled?
void* tiny_tcache_try_pop(int class_idx);             // BASE or NULL

実装は tiny_next_store/load() に委譲して next layout を SSOT 化するPhase 13 の教訓を踏襲)。

2.3 統合点(最小改造で ROI を出す)

Phase 14 v1 は “call site を増やさない” ため、統合点は unified_cache_push/pop の内部に置く。

  • unified_cache_push() 先頭:
    • tcache が enabled なら tiny_tcache_try_push() を試し、成功なら即 return配列アクセス無し
    • 失敗cap overflowなら既存の array push にフォールバック
  • unified_cache_pop() 先頭:
    • tcache が enabled なら tiny_tcache_try_pop() を試し、成功なら即 return配列アクセス無し
    • miss なら既存の array pop にフォールバック

これにより、FastLane/legacy/他経路の caller を改造せずに効果を出せる。


3. Invariants / Fail-Fast

  • tcache に格納するのは BASE pointer のみUSER は入れない)
  • 一つの block は tcache or unified_cache のどちらかにしか居ない(重複禁止)
  • count <= cap を常に守るdebug build で assert
  • next pointer の読み書きは tiny_next_store/load のみ(直書き禁止)

Fail-fastdebug のみ):

  • cap overflow をワンショットで記録(必要なら stats
  • base が怪しい値(<4096 等)の場合 abort既存 guard パターン)

4. A/B 計測計画(同一バイナリ)

ENV:

  • HAKMEM_TINY_TCACHE=0/1default 0
  • HAKMEM_TINY_TCACHE_CAP=64(研究用、必要なら)

ベンチ:

  • Mixed: scripts/run_mixed_10_cleanenv.sh
  • 追加: C6-heavy 5-run回帰がないこと

GO/NO-GO:

  • GO: mean +1.0% 以上
  • NO-GO: mean -1.0% 以下
  • NEUTRAL: ±1.0% → freeze

5. リスクと対策

リスク 1: 追加 branch の固定費が勝つPhase 11 の再来)

対策:

  • env gate は cached readgetenv を hot path に置かない)
  • unified_cache_push/pop 内の “1回だけ if” に限定call site helper を増やさない)

リスク 2: next layout の齟齬C7/C0 など)

対策:

  • next は SSOT: tiny_next_store/load を必須化
  • C7 preserve header の research knob とは独立Phase 13 v1 は freeze

リスク 3: tcache が大きすぎて locality を壊す

対策:

  • v1 は cap=64 をデフォルトglbic tcache 相当)
  • cap の探索は research knob として後段で行う

6. 期待値(当たり筋)

  • tcache hit 率が高い場合、配列アクセス・FIFO の古い再利用を回避できる
  • “system malloc が速い” の差分tcache 的挙動)に寄せる最短の一手

Update2025-12-15

v1 の統合点(core/front/tiny_unified_cache.h)だけでは、現行の main alloc hot pathtiny_hot_alloc_fast())が tcache を消費しないため、 HAKMEM_TINY_TCACHE=1 のとき tcache が “sink” になりやすい。

次は hot pathcore/box/tiny_front_hot_box.h)へ pop/push を接続して、通電した状態で再 A/B を取るPhase 14 v2:

  • docs/analysis/PHASE14_POINTER_CHASE_REDUCTION_2_NEXT_INSTRUCTIONS.md