125 lines
5.0 KiB
Markdown
125 lines
5.0 KiB
Markdown
|
|
# Free Front v3 設計メモ
|
|||
|
|
|
|||
|
|
## 目的
|
|||
|
|
|
|||
|
|
Mixed 16–1024B における free hotpath(`free` ≈ 23–36%, `tiny_alloc_gate_fast` ≈ 22%)を、
|
|||
|
|
「header 読み + route 決定 + 1 回の dispatch」に近づけることを目標に、free front v3 の構造を整理する。
|
|||
|
|
|
|||
|
|
v6/vULTRA でやりたかった「lookup を避ける」「TLS 所有で早期 free」を、free 前段の設計に統合する。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 現状 free front のフローとボトルネック
|
|||
|
|
|
|||
|
|
### 現状フロー(簡略図)
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
free
|
|||
|
|
→ hak_free_at
|
|||
|
|
→ fg_classify_domain
|
|||
|
|
→ fg_tiny_gate
|
|||
|
|
→ tiny_free_gate_try_fast
|
|||
|
|
→ hak_tiny_free_fast_v2
|
|||
|
|
→ ss_fast_lookup(ptr)
|
|||
|
|
→ slab_index_for(ptr)
|
|||
|
|
→ tiny_get_class_from_ss()
|
|||
|
|
→ TLS push / remote / pool free...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`free_tiny_fast` 相当の処理は概ね次のステップから成る:
|
|||
|
|
|
|||
|
|
1. header 読み取り + magic check(OK)
|
|||
|
|
2. class_idx 抽出(OK)
|
|||
|
|
3. stats increment(OK)
|
|||
|
|
4. C7 ULTRA check(ENV gate)
|
|||
|
|
5. C7 v3 check(ENV gate)
|
|||
|
|
6. `tiny_route_for_class()` 呼び出し(毎 free)
|
|||
|
|
7. v4/v5/v6 など複数の ENV check
|
|||
|
|
8. `tiny_route_is_heap_kind()` で heap/legacy 判定
|
|||
|
|
9. `tiny_front_v3_snapshot_get()` で front snapshot/TLS 判定
|
|||
|
|
10. `ss_fast_lookup(base)` + `slab_index_for()` で Superslab/スラブ index 解決
|
|||
|
|
11. Larson cross-thread check(owner/TLS 判定)
|
|||
|
|
12. 最後に route に応じた switch/case で実 free 実行
|
|||
|
|
|
|||
|
|
### 問題点
|
|||
|
|
|
|||
|
|
- `tiny_route_for_class()` を free 毎に呼んでいる(class→route は snapshot で cache 可能)。
|
|||
|
|
- `tiny_front_v3_snapshot_get()` を毎 free で呼んでいる。
|
|||
|
|
- `ss_fast_lookup` + `slab_index_for` が free 前段にぶら下がっており、
|
|||
|
|
「lookup を避ける」という v6/vULTRA の目標と構造的に衝突している。
|
|||
|
|
- C7 ULTRA / v4 / v5 / v6 など複数の ENV 判定が HotPath に並んでいて、branch mispredict の要因になっている。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## free front v3 の目標
|
|||
|
|
|
|||
|
|
free front v3 では、次の 3 点を達成する:
|
|||
|
|
|
|||
|
|
1. **route 決定を snapshot に閉じ込める**
|
|||
|
|
- `tiny_route_for_class()` の結果や各種 ENV を、起動時/スナップショット更新時に `route_kind[class_idx]` テーブルに焼き込む。
|
|||
|
|
- free 時には「header→class_idx→route_kind」をテーブル 1 回参照で決める。
|
|||
|
|
|
|||
|
|
2. **ENV check を HotPath から外す**
|
|||
|
|
- C7 ULTRA / v4 / v5 / v6 などの ON/OFF 判定は snapshot 初期化時に反映し、
|
|||
|
|
free のホットパスでは ENV を直接読まない。
|
|||
|
|
|
|||
|
|
3. **lookup(ss_fast_lookup/slab_index_for)を “本当に必要な場面だけ” に限定**
|
|||
|
|
- C6/C5/C4 など Core v6/Tiny/v3 が TLS 所有を持っているクラスでは、`small_tls_owns_ptr_v6` や C7 ULTRA の mask 判定で Superslab lookup を飛ばす。
|
|||
|
|
- Superslab/pool v1 経路でのみ lookup を使い、free front v3 の基本ルートからは排除する。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 理想的な free front v3 の形(イメージ)
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
typedef struct FreeRouteSnapshotV3 {
|
|||
|
|
uint8_t route_kind[NUM_SMALL_CLASSES]; // enum free_route_kind_t
|
|||
|
|
// v6/v3/pool/legacy 向けの補助情報(policy pointer 等)は別テーブルで
|
|||
|
|
} FreeRouteSnapshotV3;
|
|||
|
|
|
|||
|
|
const FreeRouteSnapshotV3* free_front_v3_snapshot_get(void);
|
|||
|
|
|
|||
|
|
void hak_free(void* ptr) {
|
|||
|
|
uint8_t header = *(uint8_t*)((uintptr_t)ptr - 1);
|
|||
|
|
uint32_t class_idx = header & HEADER_CLASS_MASK;
|
|||
|
|
|
|||
|
|
const FreeRouteSnapshotV3* snap = free_front_v3_snapshot_get();
|
|||
|
|
free_route_kind_t route = snap->route_kind[class_idx];
|
|||
|
|
|
|||
|
|
switch (route) {
|
|||
|
|
case FREE_ROUTE_TINY_V3:
|
|||
|
|
hak_tiny_free_fast_v3(ptr, class_idx, snap);
|
|||
|
|
return;
|
|||
|
|
case FREE_ROUTE_CORE_V6_C6:
|
|||
|
|
small_free_fast_v6(ptr, class_idx, small_heap_ctx_v6(),
|
|||
|
|
snap->core_v6_policy);
|
|||
|
|
return;
|
|||
|
|
case FREE_ROUTE_POOL_V1:
|
|||
|
|
hak_pool_free(ptr, 0, 0);
|
|||
|
|
return;
|
|||
|
|
// ... 他ルート(ULTRA, legacy など)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
ここでは:
|
|||
|
|
- header→class_idx→route_kind が front v3 の責務。
|
|||
|
|
- route_kind に v6/v3/pool/legacy の組み合わせや ENV の影響がすべて反映される。
|
|||
|
|
- 下流の箱(v6/v3/pool)は「自分の free を実行する」ことだけに集中できる。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## FREE-FRONT-V3-0 のゴール
|
|||
|
|
|
|||
|
|
このドキュメントでは、以下を設計レベルで固定する:
|
|||
|
|
|
|||
|
|
- 現状 free front のスタックと perf 上のボトルネック(route 二重チェック、ENV 多段チェック、lookup の位置)。
|
|||
|
|
- free front v3 で目指す構造(header 読み+class_idx 判定+snapshot route 決定+1回の dispatch)。
|
|||
|
|
- 以降のフェーズで:
|
|||
|
|
- `free_front_v3_env_box.h` のような ENV→snapshot 初期化箱を作る。
|
|||
|
|
- `hak_free` に free front v3 の接続を 1 箇所だけ差し込む。
|
|||
|
|
- Mixed で free/gate の self% を A/B 測定する。
|
|||
|
|
|
|||
|
|
実装は次フェーズ(FREE-FRONT-V3-1 以降)のタスクとし、ここでは「どこを削るか」「どこを HotPath から外すか」の設計を記録する。
|
|||
|
|
|