Files
hakmem/PHASE_ML2_CHATGPT_RESPONSE_FASTLANE.md
2025-12-14 16:28:23 +09:00

273 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PHASE ML2: 外部LLM回答Front FastLane / Layer Collapse
## 0. 位置づけ
- 本ドキュメントは、`PHASE_ML2_CHATGPT_QUESTIONNAIRE_FASTLANE.md` への外部レビュー回答を記録する。
- 次フェーズの設計/実装は、本回答を踏まえつつ **hakmem 側の既存 Box/ENV/命名**に合わせて落とし込む。
## 1. 外部回答の要点(抜粋)
### Q1: 優先順位
1. **A) Front FastLanefront層の 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 の 5065%**が現実的。
- **70%+**を狙うなら、Front の collapseAに加えて、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 FastLanefront層の 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/配置差に負ける)。
* **Q5mimallocに追いつく現実ライン**
* wrapper→gate→policy→route→handler を “階層のまま”維持すると、上限は概ね **mimallocの5065%** が現実的(あなたの現状 0.4台→0.5台を狙うのは十分射程)。
* **70%+** を狙うには、少なくとも
1. front層の collapseAに加えて、
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 1allocのみ fastlane、対象クラス限定**
* `hak_fastlane_try_alloc()` を実装size→class→route の collapse
* まずは **“Tiny内で完結するクラスだけ”** に限定class_maskで制御
* fail は必ず `hak_cold_alloc_fallback()` に落とす境界1箇所
**Phase 2freeも fastlane、ただし Fail-fast 強め)**
* `hak_fastlane_try_free()` 実装。
* “判定が曖昧”なものは全部 fallback性能より安全優先で開始
### 4.3 A/B コマンドMixed 10-run
repo に **cleanenv 10-run** スクリプトがあるので、それを基準にします。
**A: FastLane OFFbaseline**
```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%** → freezeresearch箱として保持
* **NO-GO**: mean **-1.0% 以下** → rollbackして freeze
> 分岐形だけの調整で -1.71% を踏んだ例があるので、「branch-miss率が下がった」だけでは GO にしないbranch数/コードサイズ増の方が効く)。
---
## 5. リスクと対策(戻せる手段込み)
### リスク1FastLaneが “二重分岐” を生み、コードが太って逆効果
* **症状**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環境汚染を排除。
### リスク3Fail-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等の思想があるなら同型で
### リスク4FastLaneだけで目標mimalloc 50%)に届かない
* **現実**Aは「全呼び出しの固定費」を下げるが、mimalloc差の大きな部分が “ptr→meta” なら A単独では頭打ち。
* **対策(ロードマップ)**
* Phase ML2Aで 0.5台に入らない場合、次の章は **Bptr→meta O(1) を mid/pool に波及)** を本線にする。
* Aで FastLane を作っておくと、B/Cの導入点入口が固定され、以後の実験がやりやすい境界の一本化勝ち筋
---
作成日: 2025-12-14
記録者: Task agent