273 lines
12 KiB
Markdown
273 lines
12 KiB
Markdown
|
|
# PHASE ML2: 外部LLM回答(Front FastLane / Layer Collapse)
|
|||
|
|
|
|||
|
|
## 0. 位置づけ
|
|||
|
|
|
|||
|
|
- 本ドキュメントは、`PHASE_ML2_CHATGPT_QUESTIONNAIRE_FASTLANE.md` への外部レビュー回答を記録する。
|
|||
|
|
- 次フェーズの設計/実装は、本回答を踏まえつつ **hakmem 側の既存 Box/ENV/命名**に合わせて落とし込む。
|
|||
|
|
|
|||
|
|
## 1. 外部回答の要点(抜粋)
|
|||
|
|
|
|||
|
|
### Q1: 優先順位
|
|||
|
|
|
|||
|
|
1. **A) Front FastLane(front層の Layer Collapse)**
|
|||
|
|
2. **B) ptr→meta O(1) を mid/pool に波及(segment/mask)**
|
|||
|
|
3. **C) 触るメモリ削減(geometry/metadata)**
|
|||
|
|
|
|||
|
|
理由: 直近の学び(重複排除/ENV・TLS読み回数削減が勝ち筋、diet/別バイナリ比較は壊れやすい)と整合するため。
|
|||
|
|
|
|||
|
|
### 推奨案: A) Front FastLane の骨子
|
|||
|
|
|
|||
|
|
- wrapper→gate→policy→route を **Hot側で1箱に畳む**
|
|||
|
|
- Cold側へ落ちるのは **単一フォールバック**(境界1箇所)
|
|||
|
|
- “分岐形”より **分岐数/命令数/断片化**の削減を優先(Zen で branch miss は飽和しやすい)
|
|||
|
|
- A/B は **同一バイナリで ENV トグル**(削除/追加で別バイナリ比較にしない)
|
|||
|
|
|
|||
|
|
### GO/NO-GO(提案)
|
|||
|
|
|
|||
|
|
- Mixed 10-run mean:
|
|||
|
|
- GO: **+1.0% 以上**
|
|||
|
|
- NEUTRAL: **±1.0%**(freeze)
|
|||
|
|
- NO-GO: **-1.0% 以下**(rollback/freeze)
|
|||
|
|
|
|||
|
|
### “mimalloc に追いつく”の現実ライン(提案)
|
|||
|
|
|
|||
|
|
- 多層構造(wrapper→gate→policy→route→handler)を維持したままだと概ね **mimalloc の 50–65%**が現実的。
|
|||
|
|
- **70%+**を狙うなら、Front の collapse(A)に加えて、free側 ptr→meta を O(1) 化(B)がほぼ必須。
|
|||
|
|
|
|||
|
|
## 2. 外部回答(原文)
|
|||
|
|
|
|||
|
|
以下は外部LLMの回答本文(チャット貼り付け)を、そのまま保持する。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
はい、いま **hakmem_private** 側の資料は参照できています。少なくともご指定の **`AGENTS.md`(Box Theory ルール)**、および Phase5 の A/B の学び(例:別バイナリ比較が壊れる件、Mixed 10-run 手順)を repo から確認できました。
|
|||
|
|
|
|||
|
|
以下、**PHASE ML2 の指定フォーマット**(1枚サマリ→Box図→API一覧→A/B手順→リスク対策)で返します。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 1枚サマリ
|
|||
|
|
|
|||
|
|
* **Q1(優先順位)結論**
|
|||
|
|
1位 **A) Front FastLane(front層の Layer Collapse)**
|
|||
|
|
2位 **B) ptr→meta O(1) を mid/pool に波及(segment/mask)**
|
|||
|
|
3位 **C) 触るメモリ削減(geometry/metadata)**
|
|||
|
|
理由は「ROI/リスク/工数」の積で、いまの学び(“境界の冗長排除”が勝ち筋、dietは別バイナリ比較で壊れる)に最も整合するのが A。
|
|||
|
|
|
|||
|
|
* **推奨案(A: Front FastLane)の狙い**
|
|||
|
|
wrapper→gate→policy→route の “細い箱列” を **Hot側で1箱に畳み**、**Cold側へ落ちるのは単一フォールバック**(境界1箇所)にする。
|
|||
|
|
“分岐形”改善よりも **分岐数/命令数/コード断片化**を減らす方向(Zenでmis予測は飽和しやすい)に寄せる。
|
|||
|
|
|
|||
|
|
* **Box Theory 整合**
|
|||
|
|
|
|||
|
|
* 箱=責務分離、境界1箇所、ENVで戻せる、最小可視化、Fail-fast を保持(AGENTSの5原則に沿う)。
|
|||
|
|
* A/B は **同一バイナリでENVトグル**(別バイナリ比較は LTO/配置差に負ける)。
|
|||
|
|
|
|||
|
|
* **Q5(mimallocに追いつく現実ライン)**
|
|||
|
|
|
|||
|
|
* wrapper→gate→policy→route→handler を “階層のまま”維持すると、上限は概ね **mimallocの50–65%** が現実的(あなたの現状 0.4台→0.5台を狙うのは十分射程)。
|
|||
|
|
* **70%+** を狙うには、少なくとも
|
|||
|
|
|
|||
|
|
1. front層の collapse(A)に加えて、
|
|||
|
|
2. free側 ptr→meta を(mid/pool含め)O(1) に寄せる(B)
|
|||
|
|
がほぼ必須(“直TLSバケット”に近い世界は meta 到達が勝負なので)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Box 図(ASCII)
|
|||
|
|
|
|||
|
|
推奨:**A) Front FastLane**(Layer Collapse)。「概念上の箱」は維持しつつ、**Hotの入口だけ**を1本化します。
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
(ENV: HAKMEM_FRONT_FASTLANE=0/1)
|
|||
|
|
+----------------+
|
|||
|
|
| L0: EnvGateBox |
|
|||
|
|
+----------------+
|
|||
|
|
|
|
|||
|
|
v
|
|||
|
|
+------------------+ +-------------------------+
|
|||
|
|
| malloc/free shim | --> | L1: FrontFastLaneBox |
|
|||
|
|
| (very thin) | | - size->class->route |
|
|||
|
|
+------------------+ | (1 LUT + 1 LUT) |
|
|||
|
|
| - try alloc/free fast |
|
|||
|
|
| - NO stats/NO learning |
|
|||
|
|
+-------------------------+
|
|||
|
|
| \
|
|||
|
|
success --->| \ fail-fast / unknown
|
|||
|
|
v v
|
|||
|
|
+--------------------------+ +-------------------------+
|
|||
|
|
| L1a: Hot Handlers | | L2: ColdFallbackIface |
|
|||
|
|
| - Tiny/ULTRA/MID hot | | - cold_alloc(size,ci) |
|
|||
|
|
| - per-thread freelists | | - cold_free(ptr) |
|
|||
|
|
+--------------------------+ +-------------------------+
|
|||
|
|
|
|
|||
|
|
v
|
|||
|
|
+-----------------------------+
|
|||
|
|
| L3: Cold/Safe/Observable |
|
|||
|
|
| Superslab/Tier/Guard/Stats |
|
|||
|
|
| Policy/Learner snapshot swap|
|
|||
|
|
+-----------------------------+
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**“変換点は1箇所”**= `FrontFastLaneBox -> ColdFallbackIface` の **try→fallback** 接点に集約します(allocもfreeも同じ思想)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. API 一覧(推奨案A)
|
|||
|
|
|
|||
|
|
### 3.1 L0: EnvGateBox
|
|||
|
|
|
|||
|
|
目的:**同一バイナリ**で A/B、default OFF。
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// core/box/front_fastlane_env_box.h
|
|||
|
|
static inline bool hak_front_fastlane_enabled(void); // ENV: HAKMEM_FRONT_FASTLANE=0/1 (default 0)
|
|||
|
|
static inline uint32_t hak_front_fastlane_class_mask(void); // optional: which classes are handled
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 L1: FrontFastLaneBox(入口の collapse)
|
|||
|
|
|
|||
|
|
目的:wrapper/gate/policy/route を “この箱の内部” に畳む(呼び出し側から見ると1箱)。
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// core/box/front_fastlane_box.h
|
|||
|
|
|
|||
|
|
typedef struct HakFastlaneSnapshot {
|
|||
|
|
// “Hot は snapshot を読むだけ”を守る
|
|||
|
|
uint16_t max_fast_size; // e.g. 1024
|
|||
|
|
uint32_t class_mask; // which classes use fastlane
|
|||
|
|
const uint8_t* size_to_class_lut;// pointer to global LUT (no copy)
|
|||
|
|
const uint8_t* class_to_route_lut;// route-kind per class
|
|||
|
|
// optional: pointers to hot handler vtables (avoid re-reading globals)
|
|||
|
|
} HakFastlaneSnapshot;
|
|||
|
|
|
|||
|
|
static inline const HakFastlaneSnapshot* hak_fastlane_snapshot(void);
|
|||
|
|
|
|||
|
|
// returns NULL => must fallback via ColdFallbackIface (single boundary)
|
|||
|
|
static inline void* hak_fastlane_try_alloc(size_t size, const HakFastlaneSnapshot* s);
|
|||
|
|
|
|||
|
|
// returns true => handled; false => must fallback
|
|||
|
|
static inline bool hak_fastlane_try_free(void* p, const HakFastlaneSnapshot* s);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 L2: ColdFallbackIface(境界1箇所)
|
|||
|
|
|
|||
|
|
目的:HotからColdへ落ちる “唯一の穴”。
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// core/box/front_fastlane_cold_iface_box.h
|
|||
|
|
|
|||
|
|
void* hak_cold_alloc_fallback(size_t size, uint32_t class_idx, uint32_t route_kind);
|
|||
|
|
void hak_cold_free_fallback(void* p);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> ポイント:Hot側は「失敗したらこの2関数に落とす」以外の出口を持たない(境界1箇所を強制)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. A/B 手順と閾値
|
|||
|
|
|
|||
|
|
### 4.1 原則(必読の前提の再確認)
|
|||
|
|
|
|||
|
|
* **同一バイナリでENVトグル**が原則(別バイナリ比較は LTO/配置差で壊れる)。
|
|||
|
|
* perf の self% 追跡は有効だが、**頻度と二次効果**を外すとROIを誤る(“5%ルール”などの運用指針が repo にある)。
|
|||
|
|
* cleanenv の Mixed 10-run を回す(export済みENVが残ると比較が壊れる)。スクリプトが既にある。
|
|||
|
|
|
|||
|
|
### 4.2 Phase 0〜2(小パッチ順)
|
|||
|
|
|
|||
|
|
**Phase 0(完全OFFで導入:安全)**
|
|||
|
|
|
|||
|
|
* 追加:`front_fastlane_env_box.h` / `front_fastlane_box.h` / `front_fastlane_cold_iface_box.h`
|
|||
|
|
* 既存経路は一切変えず、`if (hak_front_fastlane_enabled())` を wrapper に1箇所だけ置く。
|
|||
|
|
* default: `HAKMEM_FRONT_FASTLANE=0`
|
|||
|
|
|
|||
|
|
**Phase 1(allocのみ fastlane、対象クラス限定)**
|
|||
|
|
|
|||
|
|
* `hak_fastlane_try_alloc()` を実装(size→class→route の collapse)。
|
|||
|
|
* まずは **“Tiny内で完結するクラスだけ”** に限定(class_maskで制御)。
|
|||
|
|
* fail は必ず `hak_cold_alloc_fallback()` に落とす(境界1箇所)。
|
|||
|
|
|
|||
|
|
**Phase 2(freeも fastlane、ただし Fail-fast 強め)**
|
|||
|
|
|
|||
|
|
* `hak_fastlane_try_free()` 実装。
|
|||
|
|
* “判定が曖昧”なものは全部 fallback(性能より安全優先で開始)。
|
|||
|
|
|
|||
|
|
### 4.3 A/B コマンド(Mixed 10-run)
|
|||
|
|
|
|||
|
|
repo に **cleanenv 10-run** スクリプトがあるので、それを基準にします。
|
|||
|
|
|
|||
|
|
**A: FastLane OFF(baseline)**
|
|||
|
|
|
|||
|
|
```sh
|
|||
|
|
HAKMEM_FRONT_FASTLANE=0 scripts/run_mixed_10_cleanenv.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**B: FastLane ON**
|
|||
|
|
|
|||
|
|
```sh
|
|||
|
|
HAKMEM_FRONT_FASTLANE=1 scripts/run_mixed_10_cleanenv.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**任意(perf stat:差分が出たら原因を見る)**
|
|||
|
|
|
|||
|
|
```sh
|
|||
|
|
HAKMEM_FRONT_FASTLANE=0 perf stat -e cycles,instructions,branches,branch-misses,cache-misses -- \
|
|||
|
|
./bench_random_mixed_hakmem 20000000 400 1
|
|||
|
|
|
|||
|
|
HAKMEM_FRONT_FASTLANE=1 perf stat -e cycles,instructions,branches,branch-misses,cache-misses -- \
|
|||
|
|
./bench_random_mixed_hakmem 20000000 400 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.4 GO/NO-GO 閾値(運用)
|
|||
|
|
|
|||
|
|
repo の運用指針に合わせ、まずは以下を推奨します(Phase5の方針と整合)。
|
|||
|
|
|
|||
|
|
* **GO**: Mixed 10-run mean **+1.0% 以上**
|
|||
|
|
* **NEUTRAL**: **±1.0%** → freeze(research箱として保持)
|
|||
|
|
* **NO-GO**: mean **-1.0% 以下** → rollbackして freeze
|
|||
|
|
|
|||
|
|
> 分岐形だけの調整で -1.71% を踏んだ例があるので、「branch-miss率が下がった」だけでは GO にしない(branch数/コードサイズ増の方が効く)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. リスクと対策(戻せる手段込み)
|
|||
|
|
|
|||
|
|
### リスク1:FastLaneが “二重分岐” を生み、コードが太って逆効果
|
|||
|
|
|
|||
|
|
* **症状**:branch-miss率は微改善でも、branch数増・I-cache圧でスループットが落ちる(既に同型の罠が観測されている)。
|
|||
|
|
* **対策**:
|
|||
|
|
* FastLane 入口は **「1回だけ if」**。以降は **直線 + switch/jumptable** に寄せる。
|
|||
|
|
* fallback は `__attribute__((cold))`(または別TU)に追い出し、hot 側に条件分岐を増やさない。
|
|||
|
|
* “snapshot enabled/disabled” みたいな二系統を FastLane 内で抱えない(L0で決め打ち)。
|
|||
|
|
|
|||
|
|
### リスク2:別バイナリ比較に引きずられて判断を誤る(diet最適化の罠)
|
|||
|
|
|
|||
|
|
* **症状**:箱を削ったら速くなるはずが遅い/速い、が **リンク配置差**で反転。
|
|||
|
|
* **対策**:
|
|||
|
|
* “削除”ではなく **同一バイナリ内での無効化**(ENV=0)を常態化。
|
|||
|
|
* `scripts/run_mixed_10_cleanenv.sh` を基準にし、export環境汚染を排除。
|
|||
|
|
|
|||
|
|
### リスク3:Fail-fast 条件が緩く、silent corruption に寄る
|
|||
|
|
|
|||
|
|
* **対策(Q3の要求に対応)**:
|
|||
|
|
* **fast path に入れる条件は最小**:
|
|||
|
|
* alloc:`size <= snapshot->max_fast_size` かつ `class_mask` に含まれる
|
|||
|
|
* free:`ptr` が “自分の管理領域” と O(1) で断定できるときだけ
|
|||
|
|
* **fallback 条件は広く**:
|
|||
|
|
* “確信が持てないものは全部” `hak_cold_free_fallback()`
|
|||
|
|
* **不変条件(最小)**:
|
|||
|
|
* debugビルドのみ `assert(class_idx == page_meta->class_idx)` 等
|
|||
|
|
* releaseは “ワンショットログ + disable gate”(既にmadvise guard等の思想があるなら同型で)
|
|||
|
|
|
|||
|
|
### リスク4:FastLaneだけで目標(mimalloc 50%)に届かない
|
|||
|
|
|
|||
|
|
* **現実**:Aは「全呼び出しの固定費」を下げるが、mimalloc差の大きな部分が “ptr→meta” なら A単独では頭打ち。
|
|||
|
|
* **対策(ロードマップ)**:
|
|||
|
|
* Phase ML2(A)で 0.5台に入らない場合、次の章は **B(ptr→meta O(1) を mid/pool に波及)** を本線にする。
|
|||
|
|
* Aで FastLane を作っておくと、B/Cの導入点(入口)が固定され、以後の実験がやりやすい(境界の一本化=勝ち筋)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
作成日: 2025-12-14
|
|||
|
|
記録者: Task agent
|