90 lines
7.6 KiB
Markdown
90 lines
7.6 KiB
Markdown
|
|
# POOL_V2_BOX_DESIGN (Phase68)
|
|||
|
|
|
|||
|
|
目的
|
|||
|
|
----
|
|||
|
|
- mid/smallmid (257–768B を主軸) のホットパスで pool allocator が支配的なため、TinyHotHeap v2 と同様の「Hot/Cold 分離」を pool にも導入する設計を整理する。
|
|||
|
|
- まずは箱構造と境界だけを決め、実装は後続フェーズでゲート付き A/B できるようにする(デフォルトは現行 v1 のまま)。
|
|||
|
|
|
|||
|
|
箱と境界(方針)
|
|||
|
|
-----------------
|
|||
|
|
- Hot Box: PoolHotBox v2(per-thread / per-class pool)
|
|||
|
|
- 構造: pool_page に `freelist / used / capacity / base`、pool_class に `current_page / partial_pages / full_pages / stride`。
|
|||
|
|
- 責務: alloc/free では page 内 freelist pop/push だけを扱う。Stats/学習/OS には触れない。
|
|||
|
|
- Cold Box: Superslab/Segment/Tier/Guard/Remote + pool 専用統計
|
|||
|
|
- 責務: pool_page の供給・返却、Tier/Guard 判定、OS との境界。
|
|||
|
|
- 境界は 2 箇所に集約
|
|||
|
|
- alloc 側: `pool_refill_page(class_idx)` … Hot が page を 1 枚借りる
|
|||
|
|
- free 側: `pool_page_retire(class_idx, page)` … Hot が empty page を返す
|
|||
|
|
|
|||
|
|
現行 v1/v2 の棚卸し(箱視点)
|
|||
|
|
-----------------------------
|
|||
|
|
- v1: 安定線。pool TLS freelist + shared pool を直接操作。perf 上は hak_pool_try_alloc/free, memset が支配的。
|
|||
|
|
- v2: Phase55–57 で導入した軽量化パス(TLS fast path 直線化など)だが perf 未達。`HAKMEM_POOL_V2_ENABLED` で研究箱としてゲート。
|
|||
|
|
- 共通課題: freelist pop/push と mid_desc_lookup/owner 判定がホットパスに残りすぎている。Cold/OS と混在している。
|
|||
|
|
|
|||
|
|
設計メモ(次フェーズ実装タスクの種)
|
|||
|
|
-----------------------------------
|
|||
|
|
- Hot 型
|
|||
|
|
- `pool_page_v2`, `pool_class_v2`, `pool_ctx_v2` を TinyHotHeap v2 のミニ版として定義。
|
|||
|
|
- TLS で per-thread ctx を保持し、stride/block_size を class 初期化時にセット。
|
|||
|
|
- Hot パス
|
|||
|
|
- `pool_v2_alloc(class_idx)` / `pool_v2_free(class_idx, ptr)` は current→partial→refill、freelist pop/push だけで完結させる。
|
|||
|
|
- Debug/統計/slow パスは unlikely 側に寄せる。
|
|||
|
|
- Cold IF
|
|||
|
|
- `PoolColdIface` に `refill_page` / `retire_page` を定義。初期実装は既存 pool/superslab の API を薄くラップして流用。
|
|||
|
|
- Gate/ENV
|
|||
|
|
- `HAKMEM_POOL_V2_ENABLED` / `HAKMEM_POOL_V2_CLASSES`(mask)で v1/v2 を切替。C6-heavy プロファイルから段階的に A/B する前提。
|
|||
|
|
|
|||
|
|
狙いと目標値
|
|||
|
|
------------
|
|||
|
|
- スループット目標: mid/smallmid 単体で +5〜10%(28–29M → 30–32M ops/s)をまず狙う。
|
|||
|
|
- 命令数削減: hak_pool_try_alloc/free, memset, mid_desc_lookup の self% を数ポイント下げる。
|
|||
|
|
- pf/sys は既に小さいため、CPU パスの直線化とキャッシュで効果を出す。
|
|||
|
|
|
|||
|
|
ガード
|
|||
|
|
------
|
|||
|
|
- 本ドキュメントは設計のみ。実装はすべて ENV ゲート付きで、デフォルトは v1 挙動を維持すること。
|
|||
|
|
- Superslab/OS/Stats/Learning のロジックを変えない(Cold IF で接続するだけ)。***
|
|||
|
|
|
|||
|
|
Phase69 メモ(初回 A/B と Cold IF 状況)
|
|||
|
|
----------------------------------------
|
|||
|
|
- HotBox v2 の初実装を通電(freelist/current/partial を v2 内で管理)。Cold IF はまだ posix_memalign/free を使うダミーのまま。
|
|||
|
|
- A/B(Release, min=2048/max=8192, ws=400, iters=100k, C7_SAFE, Tiny v2 OFF):
|
|||
|
|
- v2 OFF: 28.70M ops/s
|
|||
|
|
- v2 ON (classes=0x7F, Cold IF=posix_memalign): 2.15M ops/s、`alloc_refill=1630`, `free_fb_v1` 多数 → page_of 失敗で v1 free に大量フォールバック。
|
|||
|
|
- 次の一手:
|
|||
|
|
- Cold IF を v1 pool / Superslab 経路に差し替える(posix_memalign ダミーを撤去)。
|
|||
|
|
- free_fb_v1 の主因を解消する(page_of か class 判定の欠落)。必要ならヘッダに page token を持たせるなど Hot 側のトラッキングを強化。
|
|||
|
|
- A/B は C6-heavy プロファイル(pool が効くサイズ帯)で実施し、性能と stats を CURRENT_TASK.md に積む。
|
|||
|
|
|
|||
|
|
Phase70 メモ(Cold IF 差し替え・Fail-Fast 強化)
|
|||
|
|
----------------------------------------------
|
|||
|
|
- Cold IF を v1 ベースの mmap + mid_desc_register に変更し、retire は munmap に統一。HotBox v2 からは geometry/token だけを受け取り、pop/push は v2 freelist だけで完結させる方針に近づけた。
|
|||
|
|
- page_of は class/base/offset を厳密チェックし、ミスマッチ時は Fail-Fast(v2 内では v1 fallback しない)。free_fb_v1 は front 側の route ミスマッチ検知専用に狭める前提。
|
|||
|
|
- 次ステップ: C6-heavy で v2 OFF/ON を再A/Bし、`alloc_refill_fail==0`, `free_fb_v1≈0` を確認。研究箱のまま、標準は v1 を維持。
|
|||
|
|
|
|||
|
|
Phase71 メモ(v2 ON で abort, A/B 取れず)
|
|||
|
|
----------------------------------------
|
|||
|
|
- C6-heavy (min=2048/max=8192, ws=400, iters=1M, PROFILE=C7_SAFE, Tiny v2 OFF, classes=0x7F/0x1, POOL_V2_STATS=1) で v2 ON が起動直後に `hak_pool_free_v2_impl → pool_hotbox_v2_page_of` の Fail-Fast で SIGABRT。短尺 10k でも同様で stats は出ず。
|
|||
|
|
- v2 OFF では **30.57M ops/s** を確認。v2 ON はクラッシュのため比較値なし。
|
|||
|
|
- 状態: v2 alloc→v1 free 混線 or page_of 範囲判定が未整合。free_fb_v1 は front 側のみでカウントする方針のため、ページ追跡を直さないと A/B が進まない。
|
|||
|
|
- 対応方針: route/gate と page_of の整合を再確認し、v2 alloc が NULL を返さないようにするか、front で v1 fallback に落とす。安定するまでは v2 を研究箱(デフォルト OFF)のまま維持。
|
|||
|
|
|
|||
|
|
Phase72 メモ(page_of O(1) 化と長尺挙動 / 凍結判断)
|
|||
|
|
----------------------------------------------------
|
|||
|
|
- 実装の進展:
|
|||
|
|
- HotBox v2 ページ先頭に self ポインタを埋め、`POOL_PAGE_SIZE` アラインのマスク+ヘッダ読み出しで `pool_hotbox_v2_page_of()` を O(1) 化。
|
|||
|
|
- capacity はヘッダ分を差し引いた領域から算出し、freelist はヘッダ直後から carve。retire/初期化時にヘッダを必ずセット/クリア。
|
|||
|
|
- Cold IF の mmap を 64KiB アライン取得に揃え、2ページ分の OS 統計だけ積む構造に整理(Superslab 相当の geometry を模倣)。
|
|||
|
|
- 短〜中尺の挙動(C6-heavy, v2 ON, POOL_V2_STATS=1):
|
|||
|
|
- 10k〜100k/ws=400 では page_of_fail_x=0 / free_fb_v1=0 / alloc_refill 十数〜数十回で完走。構造バグ(page_of/route 混線)は解消。
|
|||
|
|
- Throughput は v1 基準より低く、短尺で ~20–25M ops/s 程度(v1≈30M)。オーダーは正しいがオーバーヘッドはまだ大きい。
|
|||
|
|
- 長尺 1M/ws=400 の挙動:
|
|||
|
|
- v2 OFF: ≈27–30M ops/s で安定完走。
|
|||
|
|
- v2 ON: 120s タイムアウトで完走せず(ハング/極端な遅さ)。page_of_fail は短尺では 0 だが、1M 長尺では perf 観点で許容できないレベルの回帰。
|
|||
|
|
- 現フェーズの結論:
|
|||
|
|
- PoolHotBox v2 の箱構造(page_of O(1)、Cold IF=v1 pool/Superslab)と Fail-Fast/統計まわりは通電し、研究用としては十分な観測性を得られた。
|
|||
|
|
- 一方で C6-heavy 長尺での極端な遅さを解消するには、page geometry / current/partial ポリシーや mid/pool 全体の設計をさらに大きく見直す必要があり、現フェーズ(Tiny v2 + mid/pool v2)での対応範囲を超える。
|
|||
|
|
- そのため、PoolHotBox v2 は **現行フェーズでは研究箱として凍結** し、運用デフォルトは引き続き `HAKMEM_POOL_V2_ENABLED=0`(v1 pool)のままとする。
|
|||
|
|
- mid/smallmid のさらなる最適化(mimalloc 7〜8割到達)を狙う場合は、将来の v3 テーマとして pool/mid の Hot/Cold 再設計を検討する(本ドキュメントはその出発点とする)。***
|