2025-12-08 21:30:21 +09:00
|
|
|
|
# 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/s(mimalloc 54.2M / system 15.3M は Phase53 より)
|
|
|
|
|
|
- perf stat (cycles:u): IPC≈2.4、page-faults≈7.4k(Phase53 と同等)
|
|
|
|
|
|
|
|
|
|
|
|
## cycles:u ホットシンボル(self%)
|
|
|
|
|
|
- hak_pool_try_alloc.part.0 … 14.7% (pool alloc ホットパス)
|
|
|
|
|
|
- worker_run … 9.2% (ドライバ側のループと malloc 呼び出しを含む)
|
|
|
|
|
|
- free / hak_free_at.constprop.0 … ~9–10%(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 を 28–29M → 30–32M(+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**(目標 30–32M に届かず、前回 28–29M から回帰)。
|
|
|
|
|
|
- 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 まわりやリング補充順序をより大胆に削らないと改善しない。次のステップとして追加の枝削減・キャッシュ導入を検討。
|
|
|
|
|
|
|
2025-12-10 14:00:57 +09:00
|
|
|
|
## Phase MD1(mid_desc_lookup TLS キャッシュ)
|
|
|
|
|
|
- 目的: C6-heavy/mid で目立つ mid_desc_lookup を TLS 1 エントリでキャッシュし、サイズが同じリクエストが続くケースで self% を削る。
|
|
|
|
|
|
- ENV ゲート: `HAKMEM_MID_DESC_CACHE_ENABLED=1`(デフォルト OFF)。miss 時は従来の `mid_desc_lookup` にフォールバック。
|
|
|
|
|
|
- baseline self%: mid_desc_lookup≈3.8%(Phase54 perf, C7_SAFE)。
|
|
|
|
|
|
- A/B(C6_HEAVY_LEGACY_POOLV1, 1M/400, flatten OFF, zero=full):
|
|
|
|
|
|
- cache OFF: 28.90M ops/s
|
|
|
|
|
|
- cache ON : 29.83M ops/s(**+3.2%**)segv/assert なし。
|
|
|
|
|
|
- Mixed 16–1024B (C7_SAFE front v3/LUT/fast classify ON): cache OFF 44.83M → ON 44.94M(+0.3%)。perf (cycles:u, release) では mid_desc_lookup は上位に出ず、self% 影響はごく小さい。
|
|
|
|
|
|
|
2025-12-08 21:30:21 +09:00
|
|
|
|
## 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 でどの改変が悪いかを切り分ける方針。
|
2025-12-09 19:34:54 +09:00
|
|
|
|
|
|
|
|
|
|
## Phase80: Pool v1 flatten 初回 A/B(C6-heavy)
|
|
|
|
|
|
|
|
|
|
|
|
- スコープ: pool v1 の自スレッドホットパス(TLS ring/lo hit)を別 Box として直線化し、mid/smallmid(C6-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 Phase2(free_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。
|
2025-12-09 21:50:15 +09:00
|
|
|
|
|
2025-12-10 09:35:18 +09:00
|
|
|
|
## Phase 82 Final: mid_desc initialization race fix と包括的 A/B ベンチ
|
|
|
|
|
|
|
|
|
|
|
|
### 根本原因の修正
|
|
|
|
|
|
- Phase 82 の full flatten が C7_SAFE モードでクラッシュしていた原因: `mid_desc_adopt()` が未初期化ミューテックスにアクセスする race condition
|
|
|
|
|
|
- C7_SAFE では TinyHeap ルーティングが C7-only であり、Pool が通常より早期に呼ばれる
|
|
|
|
|
|
- `mid_desc_init_once()` が `mid_desc_adopt()` より前に保証されていなかった
|
|
|
|
|
|
- 修正: `hak_pool_init_impl()` 冒頭で `mid_desc_init_once()` を強制実行 → 初期化順序を確定化
|
|
|
|
|
|
- この修正は本線(常に有効、すべてのプロファイルで)
|
|
|
|
|
|
|
|
|
|
|
|
### 包括的ベンチマーク結果 (C6_HEAVY_LEGACY_POOLV1, Release)
|
|
|
|
|
|
|
|
|
|
|
|
| フェーズ | 10K ops/s | 100K ops/s | 1M ops/s | 特記事項 |
|
|
|
|
|
|
|---------|-----------|-----------|---------|---------|
|
|
|
|
|
|
| **Phase 1 (ベースライン)** | 3.03M | 14.86M | 26.67M | 最適化なし、基準値 |
|
|
|
|
|
|
| **Phase 2 (Zero Mode Header)** | +5.0% | -2.7% | -0.2% | ML1: 小規模ワークロード向け |
|
|
|
|
|
|
| **Phase 3 (Full Flatten)** | +3.7% | **+6.1%** | -5.0% | 中規模(100K)で最適化効果 |
|
|
|
|
|
|
| **Phase 4 (Combined)** | -5.1% | **+8.8%** | +2.0% | **最高パフォーマンス: 100K で +8.8%** |
|
|
|
|
|
|
| **Phase 5 (C7_SAFE Safety)** | NO CRASH | NO CRASH | NO CRASH | **クラッシュ完全回避** ✅ |
|
|
|
|
|
|
|
|
|
|
|
|
### 構成別デフォルト値(本線ポリシー)
|
|
|
|
|
|
|
|
|
|
|
|
**C7_SAFE プロファイル:**
|
|
|
|
|
|
- `HAKMEM_POOL_V1_FLATTEN_ENABLED=0` (デフォルト OFF)
|
|
|
|
|
|
- `HAKMEM_POOL_ZERO_MODE=full` (デフォルト: フル zero、安全側)
|
|
|
|
|
|
- `mid_desc_init_once()` 強制実行(クラッシュ防止、常に有効)
|
|
|
|
|
|
- ベンチ時の opt-in: `HAKMEM_POOL_V1_FLATTEN_ENABLED=1` / `HAKMEM_POOL_ZERO_MODE=header` で切り替え可能
|
|
|
|
|
|
|
|
|
|
|
|
**LEGACY / 研究用プロファイル:**
|
|
|
|
|
|
- `HAKMEM_POOL_V1_FLATTEN_ENABLED=0` (デフォルト OFF)
|
|
|
|
|
|
- `HAKMEM_POOL_ZERO_MODE=full` (デフォルト: フル zero)
|
|
|
|
|
|
- ベンチ時のみ `HAKMEM_POOL_V1_FLATTEN_ENABLED=1` で opt-in
|
|
|
|
|
|
|
|
|
|
|
|
### ワークロード特性別の最適化効果
|
|
|
|
|
|
|
|
|
|
|
|
| ワークロードサイズ | 最適な構成 | 改善率 | 備考 |
|
|
|
|
|
|
|-----------------|---------|--------|------|
|
|
|
|
|
|
| 小規模 (10K) | Phase 2 (Zero Mode) | +5.0% | オーバーヘッド増で複合モードは -5.1% |
|
|
|
|
|
|
| 中規模 (100K) | Phase 4 (Combined) | **+8.8%** | **最高効果を示す領域** |
|
|
|
|
|
|
| 大規模 (1M) | Phase 4 (Combined) | +2.0% | キャッシュ圧力で効果減少 |
|
|
|
|
|
|
|
|
|
|
|
|
### 所感
|
|
|
|
|
|
|
|
|
|
|
|
mid_desc 初期化順序の修正(`mid_desc_init_once()` の強制実行)は**本線として常に有効**。これにより:
|
|
|
|
|
|
- C7_SAFE モードでの未初期化ミューテックスクラッシュを完全排除
|
|
|
|
|
|
- Flatten と Zero Mode は箱として組み込まれ、ENV で opt-in/out が可能
|
|
|
|
|
|
- デフォルト構成では両機能とも OFF(安全側)維持
|
|
|
|
|
|
|
|
|
|
|
|
性能目標(+13–25%)には未到達だが、**安全性の確保と中規模ワークロードでの +8.8% 改善** が主要な成果。1M 反復での -5%〜-0.2% 回帰は、より大規模データセットでのキャッシュ効率悪化に起因する可能性があり、今後の最適化テーマ。
|