Files
hakmem/docs/analysis/TINY_C7_ULTRA_DESIGN.md
Moe Charm (CI) 11dc9d390a Phase PERF-ULTRA-FREE-OPT-1: C4-C7 ULTRA free 薄型化
- C4-C7 ULTRA free を pure TLS push + cold segment learning に統一
- C7 ULTRA free を同じパターンに整列(likely/unlikely + FREE_PATH_STAT_INC)
- C4/C5/C6 ULTRA は既に最適化済み(統一 legacy fallback 経由)
- base/user 変換を tiny_ptr_convert_box.h マクロで統一

実測値 (Mixed 16-1024B, 1M iter, ws=400):
- Baseline (C7 のみ): 42.0M ops/s, legacy=266,943 (49.2%)
- Optimized (C4-C7): 46.5M ops/s, legacy=26,025 (4.8%)
- 改善: +9.3% (+4M ops/s)

FREE_PATH_STATS:
- C6 ULTRA: 137,319 free + 137,241 alloc (100% カバー)
- C5 ULTRA: 68,871 free + 68,827 alloc (100% カバー)
- C4 ULTRA: 34,727 free + 34,696 alloc (100% カバー)
- Legacy: 266,943 → 26,025 (−90.2%, C2/C3 のみ)

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-11 20:49:39 +09:00

191 lines
9.8 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.

# TINY_C7_ULTRA_DESIGN
## 目的
- C7 (1024B) 向け mimalloc 型超高速パスULTRAを用意し、Mixed 161024B を mimalloc の 5 割近辺まで寄せる。
- 学習層や stats の仕組みは残しつつ、C7 同一スレッドのホットパスからは極力それらを排除する。
## 箱構造
- Hot: TinyC7UltraBoxTLS freelist + C7 専用セグメントを握る同一スレッド専用箱)
- Cold: C7UltraSegmentBoxC7 専用セグメント管理。現段階では設計のみで未実装)
- 既存 Cold: Superslab / WarmPool / Guard / Remote / Stats は既存の箱のまま。ULTRA は原則触らない。
## 決定事項(芯)
1. C7 専用ページ源
- ULTRA は「C7 専用セグメント」からページを取る(将来は mmap で 2〜4MiB 単位)。
- v3/v4/Tiny v1 が握る C7 ページとは混ざらない前提。
- UF-1 時点では C7UltraSegmentBox は未実装で、C7 ページ供給は既存 v3 経由の stub とする。
2. free 時の ptr→page
- ULTRA が扱う C7 ページは C7 専用セグメント上にのみ存在すると決める。
- 将来像:
- seg = p & ~(SEG_SIZE-1) で segment 基底。
- seg が ULTRA 管理表にあれば offset / page_idx / page_meta から class=7 を取得し、ヘッダなしで freelist push。
- 管理表に無ければ既存 v3/v4 freeヘッダありにフォールバック。
3. ULTRA と v3/v4 の責務分離
- ULTRA ON: C7 アロケーションはすべて ULTRA 管理v3/v4 は C7 ページを新規に取らない)。
- ULTRA OFF: C7 は v3現行本命か v4 が処理する。
- free: 「まず ULTRA セグメントか」を判定し、ULTRA 管理外なら常に v3/v4 free へ落とすオーバーレイ構造。
- Remote/cross-thread free は ULTRA 非対応。ULTRA は同一スレッド C7 専用 TLS box として設計。
4. Fail-Fast ポリシー
- ULTRA が扱わないポインタは必ず v3/v4 側でヘッダ検証・範囲チェックを行う。
- ULTRA 内部不整合(将来フェーズ)は statsワンショットログで可視化し、可能なら v3/v4 へフォールバック。
## セグメント前提UF-3 仕様)
- SEG_SIZE: 2MiB (pow2)。seg_base = ptr & ~(SEG_SIZE-1) で判定可能にする。
- セグメント構造(イメージ):
- base, seg_size (=2MiB), page_size (=TINY_PAGE_SIZE 想定), num_pages (=seg_size/page_size)
- page_meta[num_pages]freelist/used/capacity だけを持つ軽量構造)
- free 時の判定:
- seg = p & ~(SEG_SIZE-1) で ULTRA 管理セグメントか確認。
- 管理外 → v3 freeヘッダ付き経路へフォールバック。
- 管理内 → page_idx = (p - seg_base) >> PAGE_SHIFT で page_meta を取得し、ヘッダ無しで freelist push。
- Remote/cross-thread free は UF-3 でも非対応(同一スレッド C7 専用のまま)。
## UF-4: C7 ULTRA header light研究箱
- 目的: C7 ULTRA の alloc/free から tiny_region_id_write_header の毎回実行を外し、carve 時だけに寄せる。
- 手段: freelist の next をヘッダ直後に格納してヘッダを保持し、ENV `HAKMEM_TINY_C7_ULTRA_HEADER_LIGHT` (default 0) ON のときだけ carve 時に一括書き込み。alloc はヘッダ済みならスキップ。
- Fail-Fast: ULTRA 管理外 ptr は従来どおり v3 free 経路へ落とす。
## フェーズ
- UF-1: 箱・ENV・front フックだけ stub で入れる(中身は v3 C7 経由、挙動変化なし)。
- UF-2: ULTRA TLS freelist を実装C7 ページ 1 枚を TLS で握る。同一スレッドのみ。C7 ページ供給は当面 v3/v4 経由。
- UF-3: C7UltraSegmentBox を実装し、ptr→segment mask でヘッダレス free に寄せる(セグメント 1 枚のみでも可)。
- UF-4: C7 ULTRA header light を研究箱として追加し、ON/OFF A/BMixed / C7-only 両方)で評価する。
---
## Phase PERF-ULTRA-ALLOC-OPT-1: C7 ULTRA alloc 内部最適化(実装予定)
### 背景Phase PERF-ULTRA-REBASE-1 の発見)
2025-12-11 の perf 計測C4-C7 ULTRA 全て ONで以下が判明
**ホットパス分析結果** (allocator 内部, self%):
- **C7 ULTRA alloc: 7.66%** ← **新しい最大ボトルネック**
- C4-C7 ULTRA free群: 5.41%
- gate/front前段: 2.51% ← **既に十分薄い**
- header: < 0.17% **ULTRA 経路での削減効果が出ている**
### 結論
**v6/v5/v4 のような新世代追加ではなく、既に当たりが出ている ULTRA 内部を薄くする方針に転換**
- v6/v5 C5/C4 拡張は -1233% の大幅回帰を招いた
- header gate/front は既に改善済み許容範囲
- **C7 ULTRA alloc 7.66% 5-6% に削れば全体で 2-3% の効果が期待できる**
### 実装施策
**ターゲット**: `tiny_c7_ultra_alloc()` hot path を直線化
1. **TLS ヒットパスの直線化**
- env check が残っていないか確認lazy init 後は ENV 参照すべきではない
- snapshot 取得が hot path に含まれていないか確認
- fast path を完全に直線化分岐最小化
2. **TLS freelist レイアウト最適化**
- freelist[], count などのホットデータが 1 cache line に収まるか確認
- alloc ホットデータfreelist[], countの配置を L1 キャッシュ友好的に再配置
3. **segment / page_meta アクセスの確認**
- segment learning / page_meta access が本当に slow pathキャッシュミス時だけか確認
- hot path に余分なメモリアクセスが混入していないか確認
### 計測戦略
**A/B テスト**:
- C7-only1024B固定 Mixed16-1024Bの両方で計測
- enabler: HAKMEM_TINY_C7_ULTRA_FREE_ENABLED=1
**perf 計測**:
- 最適化前後で `perf report --stdio` により self% 7.66% 5-6% まで落ちるか確認
- throughput 改善量ops/sを測定
### 期待値
- **alloc パス**: 5-10% の削減self% 2% 削減で全体効果 2-3%
- **全体 Mixed throughput**: +2-3M ops/s31.6M ops/s 33-35M ops/s 想定
### 次ステップ
1. 実装完了後perf 再計測で効果を検証
2. self% 5-6% に達したら次フェーズC4-C7 ULTRA free群 5.41% の軽量化
3. それ以上の改善は narrow pointpage_of/segment 判定, so_alloc系の検討が必要
---
## Phase PERF-ULTRA-ALLOC-OPT-1 実装完了 (2025-12-11)
### 設計判断
**方針転換**: 寄生型の C7 ULTRA_FREE_BOX は設計的に不整合と判断し撤去
- C7 ULTRA C4/C5/C6 ULTRA と異なり専用 segment + TLS を持つ独立サブシステム
- 寄生型パターンは他の ULTRA クラスには適用可能だがC7 には不適合
- **C7 tiny_c7_ultra.c 内部だけで最適化する方針に切り替え**
### 実装内容
1. **寄生型パスの削除**
- `core/box/tiny_c7_ultra_free_box.{h,c}` を削除
- `core/box/tiny_c7_ultra_free_env_box.h` を削除
- Makefile から `tiny_c7_ultra_free_box.o` を削除
- malloc_tiny_fast.h を元の `tiny_c7_ultra_alloc()` / `tiny_c7_ultra_free()` 呼び出しに戻す
2. **TLS 構造の最適化** (`tiny_c7_ultra_box.h`)
- **count struct の先頭に移動** (L1 cache locality 向上)
- 配列ベース TLS キャッシュに変更capacity=128, C6 と同じ
- freelist: linked-list BASE pointer 配列に変更
- cold フィールドseg_base/seg_end/segment metaを後方に配置
3. **alloc の純 TLS pop 化** (`tiny_c7_ultra.c`)
- **hot path: 1 分岐のみ** (count > 0)
- TLS access は 1 回のみctx に cache
- ENV check を呼び出し側malloc_tiny_fast.hに移動
- segment/page_meta アクセスは refill 時cold pathのみ
4. **free の UF-3 segment learning 維持**
- 最初の free で segment 学習seg_base/seg_end を TLS に記憶)
- 以降は seg_base/seg_end 範囲チェック → TLS push
- 範囲外は v3 free にフォールバック
### 実測値 (Mixed 16-1024B, 1M iter, ws=400)
**Perf profile (self%)**:
- `tiny_c7_ultra_alloc`: **7.66%** (維持 - 既に最適化済み)
- `tiny_c7_ultra_free`: **3.50%**
- Throughput: **43.5M ops/s** (1M iterations)
**注**: 今回の実装で内部構造を array-based に変更し、pure TLS pop パターンに統一したが、
perf self% は baseline と同等。これは元の linked-list 実装も既に効率的だったことを示す。
今後の最適化は refill ロジックsegment 取得部分)や page_meta 管理の軽量化が必要。
### 評価
**部分達成**:
- 寄生型パターンの撤回による設計一貫性の回復: **成功**
- Array-based TLS cache への移行: **成功**
- pure TLS pop パターンへの統一: **成功**
- perf self% 削減7.66% → 5-6%: **未達成** (既に最適)
**次のアクション**:
1. refill path の最適化segment 取得の軽量化)
2. page_meta 管理の簡略化bitmap 化など)
3. C4-C7 ULTRA free 群5.41%)の最適化に移行
---
## 設計整理: C7 独立 vs C4/C5/C6 寄生
**C7 ULTRA**: 独立サブシステムtiny_c7_ultra.c に閉じた segment + TLS
- 専用の segment 管理2MiB Segment / 64KiB Page
- 独自の TLS contextfreelist + page_meta + segment pointers
- alloc/free/refill が全て tiny_c7_ultra.c 内で完結
- 既存 allocatorv1/v3/poolには依存しないfallback 時を除く)
**C4/C5/C6 ULTRA**: 寄生型(既存 allocator 上の TLS cache
- 専用 segment は持たない
- 既存 allocatorv1/v3/poolに「寄生」して TLS キャッシュだけ追加
- free 時に TLS push、alloc 時に TLS popキャッシュミス時は既存 allocator へ fallback
- minimal overhead で既存パスに統合可能
次フェーズPERF-ULTRA-FREE-OPT-1では、これら ULTRA の free 側TLS push パス)を統一された形に薄くする。