Files
hakmem/docs/analysis/POOL_V2_BOX_DESIGN.md

90 lines
7.6 KiB
Markdown
Raw Normal View History

# POOL_V2_BOX_DESIGN (Phase68)
目的
----
- mid/smallmid (257768B を主軸) のホットパスで pool allocator が支配的なため、TinyHotHeap v2 と同様の「Hot/Cold 分離」を pool にも導入する設計を整理する。
- まずは箱構造と境界だけを決め、実装は後続フェーズでゲート付き A/B できるようにする(デフォルトは現行 v1 のまま)。
箱と境界(方針)
-----------------
- Hot Box: PoolHotBox v2per-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: Phase5557 で導入した軽量化パス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%2829M → 3032M 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/BRelease, 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-Fastv2 内では 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 基準より低く、短尺で ~2025M ops/s 程度v1≈30M。オーダーは正しいがオーバーヘッドはまだ大きい。
- 長尺 1M/ws=400 の挙動:
- v2 OFF: ≈2730M 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 再設計を検討する(本ドキュメントはその出発点とする)。***