Files
hakmem/docs/analysis/TINY_C7_ULTRA_DESIGN.md
Moe Charm (CI) 753909fa4d Phase PERF-ULTRA-ALLOC-OPT-1 (改訂版): C7 ULTRA 内部最適化
設計判断:
- 寄生型 C7 ULTRA_FREE_BOX を削除(設計的に不整合)
- C7 ULTRA は C4/C5/C6 と異なり専用 segment + TLS を持つ独立サブシステム
- 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/free 呼び出しに戻す

2. TLS 構造の最適化 (tiny_c7_ultra_box.h)
   - count を struct 先頭に移動(L1 cache locality 向上)
   - 配列ベース TLS キャッシュに変更(cap=128, C6 同等)
   - freelist: linked-list → BASE pointer 配列
   - cold フィールド(seg_base/seg_end/meta)を後方配置

3. alloc の純 TLS pop 化 (tiny_c7_ultra.c)
   - hot path: 1 分岐のみ(count > 0)
   - TLS access は 1 回のみ(ctx に cache)
   - ENV check を呼び出し側に移動
   - segment/page_meta アクセスは refill 時(cold path)のみ

4. free の UF-3 segment learning 維持
   - 最初の free で segment 学習(seg_base/seg_end を TLS に記憶)
   - 以降は範囲チェック → TLS push
   - 範囲外は v3 free にフォールバック

実測値 (Mixed 16-1024B, 1M iter, ws=400):
- tiny_c7_ultra_alloc self%: 7.66% (維持 - 既に最適化済み)
- tiny_c7_ultra_free self%: 3.50%
- Throughput: 43.5M ops/s

評価: 部分達成
- 設計一貫性の回復: 成功
- Array-based TLS cache 移行: 成功
- pure TLS pop パターン統一: 成功
- perf self% 削減(7.66% → 5-6%): 未達成(既に最適)

C7 ULTRA は独立サブシステムとして tiny_c7_ultra.c に閉じる設計を維持。
次は refill path 最適化または C4-C7 ULTRA free 群の軽量化へ。

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

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

8.9 KiB
Raw Blame History

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 拡張は -12〜33% の大幅回帰を招いた
  • 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%)の最適化に移行