Files
hakmem/docs/analysis/MID_LARGE_CPU_HOTPATH_ANALYSIS.md
2025-12-09 21:50:15 +09:00

79 lines
7.5 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.

# MID/Large CPU Hotpath (Phase54)
- 条件: `./bench_mid_large_mt_hakmem 1 1000000 400 1` (Release)
`HAKMEM_TINY_HEAP_PROFILE=C7_SAFE`, `HAKMEM_TINY_C7_HOT=1`, `HAKMEM_TINY_HOTHEAP_V2=0`, `HAKMEM_TINY_LARSON_FIX=1`
- スループット: HAKMEM ≈28.1M ops/smimalloc 54.2M / system 15.3M は Phase53 より)
- perf stat (cycles:u): IPC≈2.4、page-faults≈7.4kPhase53 と同等)
## cycles:u ホットシンボルself%
- hak_pool_try_alloc.part.0 … 14.7% pool alloc ホットパス)
- worker_run … 9.2% (ドライバ側のループと malloc 呼び出しを含む)
- free / hak_free_at.constprop.0 … ~910%glibc free 連携+自前 free
- __memset_avx2_unaligned_erms … ~9%pool 初期化/clear と推定)
- mid_desc_lookup … 3.8%
- hak_super_lookup … 1.4%
- hak_pool_free.part.0 … 0.7%
## 所感
- pool 系hak_pool_try_alloc / hak_pool_freeと free/memset が支配的で、mid_desc_lookup と super_lookup も目立つ。
- kernel 枠の大きな inclusive% は free/memset 配下にぶら下がっており、userland 側の pool/front の命令数削減が効果的そう。
## Phase55 方針pool allocator ホットパス軽量化)
- スコープ: core/hakmem_pool.c / core/hakmem_smallmid.c / core/box/pool_* の pool fast path。
- hak_pool_try_alloc を直線化:
- 「TLS/local freelist hitなら即 return」を先頭に寄せ、debug/統計/slow は unlikely 側へ。
- mid_desc_lookup/クラス情報は入口で 1 回だけ計算し、TLS へのキャッシュを検討。
- hak_pool_free / hak_free_at:
- self-thread free は pool push を最優先にし、cross-thread/debug は unlikely に寄せる。
- free 時の memset/初期化が不要なケースを洗い出し、スキップ余地をメモ。
- mid_desc_lookup のキャッシュ:
- size→class→desc を入口で 1 回だけ決める仕組み(既存キャッシュの再利用も含め)を検討。
- 成功ラインbench_mid_large_mt_hakmem 1 1000000 400 1, Release):
- ops/s を 2829M → 3032M+5〜10%)へ。
- perf report で hak_pool_try_alloc + free 周辺 self% が数ポイント低下。
## Phase56 結果pool fast path 初期実装)
- 変更: PoolBlock→user 変換をヘルパに寄せ、TLS ring/lo pop と self-thread free push を直線化。owner 判定は mid_desc の 1 回 lookup で共有。
- ベンチC6-heavy, ws=256, iters=20k, C7_SAFE, v2 OFF: **25.9M ops/s**(目標 3032M に届かず、前回 2829M から回帰)。
- perf stat同条件 1M/400: cycles=225,766,496、instructions=528,335,613、task-clock=57.88ms、ops/s≈25.7M。
- 所感: fast-path整理だけでは効果薄く、むしろ低下。pool 内の memset/desc まわりやリング補充順序をより大胆に削らないと改善しない。次のステップとして追加の枝削減・キャッシュ導入を検討。
## Phase57 回帰トリアージpool v2 をゲート化)
- 変更: `HAKMEM_POOL_V2_ENABLED` を追加し、v1/v2 の pool 実装を env で切替。細分スイッチとして `HAKMEM_POOL_V2_BLOCK_TO_USER` / `HAKMEM_POOL_V2_TLS_FAST_PATH` を用意(デフォルト ON, v2 時のみ有効)。
- ベンチC6-heavy, 1M/400, Release:
- v1 (POOL_V2_ENABLED=0): **27.40M ops/s**
- v2 (POOL_V2_ENABLED=1): **24.73M ops/s**
- 所感: v2 の変更が回帰要因と判明。標準は v1 に戻し、スイッチ単位の A/B でどの改変が悪いかを切り分ける方針。
## Phase80: Pool v1 flatten 初回 A/BC6-heavy
- スコープ: pool v1 の自スレッドホットパスTLS ring/lo hitを別 Box として直線化し、mid/smallmidC6-heavyでの ops/s 向上を狙う。pool v2 は引き続き研究箱のまま触らない。
- 実装: `core/hakmem_pool.c``hak_pool_try_alloc_v1_flat` / `hak_pool_free_v1_flat` を追加し、TLS ring/lo hit 時は最小限の分岐だけで pop/push する経路を用意。miss 時や cross-thread/slow は従来の `_v1_impl` にフォールバックする構造にし、ENV `HAKMEM_POOL_V1_FLATTEN_ENABLED`デフォルト0`HAKMEM_POOL_V1_FLATTEN_STATS` で切替・統計を制御。
- ベンチ条件: `./bench_mid_large_mt_hakmem 1 1000000 400 1`Release`HAKMEM_BENCH_MIN_SIZE=257`, `MAX_SIZE=768`, `HAKMEM_TINY_HEAP_PROFILE=C7_SAFE`, `HAKMEM_TINY_C7_HOT=1`, `HAKMEM_TINY_HOTHEAP_V2=0`, `HAKMEM_SMALL_HEAP_V3_ENABLED=1`, `HAKMEM_SMALL_HEAP_V3_CLASSES=0x80`, `HAKMEM_POOL_V2_ENABLED=0`, `HAKMEM_POOL_V1_FLATTEN_STATS=1`
- A/B 結果:
- flatten OFF (`POOL_V1_FLATTEN_ENABLED=0`): Throughput ≈ **23.12M ops/s**`[POOL_V1_FLAT] alloc_tls_hit=0 alloc_fb=0 free_tls_hit=0 free_fb=0`
- flatten ON (`POOL_V1_FLATTEN_ENABLED=1`): Throughput ≈ **25.50M ops/s**(約 +10%)、`alloc_tls_hit=499,870 alloc_fb=230 free_tls_hit=460,450 free_fb=39,649`
- 所感:
- Pool v1 の TLS fast path を分離・直線化するだけで、狙っていた +5〜10% の上限付近まで改善が出た。まだ free_fb がそこそこ残っており、page_of / 自スレ判定の精度を上げて free_fb を減らす余地がある。
- デフォルト運用は安全側を維持するため `HAKMEM_POOL_V1_FLATTEN_ENABLED=0` のままとし、C6-heavy/mid ベンチや実験時にのみ flatten 経路を ON にする Box として扱う。
## Phase81: Pool v1 flatten Phase2free_fb 理由分解)
- 変更: flatten stats に free fallback の内訳を追加page_null / not_mine / other。free で mid_desc が取れない場合は page_null、owner 不一致や TLS 無効による fallback は not_mine、それ以外は other としてカウント。
- ベンチ条件: `./bench_mid_large_mt_hakmem 1 1000000 400 1`Release`HAKMEM_TINY_HEAP_PROFILE=LEGACY`, `HAKMEM_TINY_HOTHEAP_V2=0`, `HAKMEM_POOL_V2_ENABLED=0`, `HAKMEM_POOL_V1_FLATTEN_ENABLED=1`, `HAKMEM_POOL_V1_FLATTEN_STATS=1`
- A/B:
- flatten OFF: **23.68M ops/s**、stats すべて 0。
- flatten ON : **25.90M ops/s**(約 +9.4%)、`alloc_tls_hit=499,870 alloc_fb=230 free_tls_hit=460,060 free_fb=40,039 page_null=40,039 not_mine=0 other=0`
- 所感: free fallback のほぼすべてが「mid_desc が取れず page=null」で発生している。owner mismatch はゼロ。今後は page_of/mid_desc 判定の精度を上げることで free_fb を減らす余地がある。
## Phase82: mid_desc マスク整合による free_fb 削減
- 変更: `mid_desc_register/lookup/adopt` が扱うページアドレスを `POOL_PAGE_SIZE` で正規化し、64KiB に未アラインな mmap でも mid_desc_lookup が一致するように修正。これにより false negative の page_null を減らす。
- ベンチ同条件、flatten ON, Release, tiny/pool v2 OFF, LEGACY tiny:
- flatten OFF: **23.68M ops/s**(参考値・前フェーズと同じ)。
- flatten ON : **26.70M ops/s**(約 +13% vs OFF`alloc_tls_hit=499,871 alloc_fb=229 free_tls_hit=489,147 free_fb=10,952 page_null=3,476 not_mine=7,476 other=0`
- 所感: page_null が大幅減≈40k→≈3.4k。not_mine が顕在化したため、次は owner 判定/自スレ判定の精度を軽く見直す余地がある。デフォルトは引き続き flatten OFF安全側で、bench/実験時のみ ON。
### 安全側の運用メモ
- C7_SAFE / C7_ULTRA_BENCH プロファイルと pool v1 flatten の組み合わせではクラッシュ報告があるため、`HAKMEM_TINY_HEAP_PROFILE` がこれらのときは flatten を強制 OFFENV を立てても無効化としている。LEGACY や研究用途でのみ flatten を opt-in する方針。