Phase ML1: Pool v1 memset 89.73% overhead 軽量化 (+15.34% improvement)

## Summary
- ChatGPT により bench_profile.h の setenv segfault を修正(RTLD_NEXT 経由に切り替え)
- core/box/pool_zero_mode_box.h 新設:ENV キャッシュ経由で ZERO_MODE を統一管理
- core/hakmem_pool.c で zero mode に応じた memset 制御(FULL/header/off)
- A/B テスト結果:ZERO_MODE=header で +15.34% improvement(1M iterations, C6-heavy)

## Files Modified
- core/box/pool_api.inc.h: pool_zero_mode_box.h include
- core/bench_profile.h: glibc setenv → malloc+putenv(segfault 回避)
- core/hakmem_pool.c: zero mode 参照・制御ロジック
- core/box/pool_zero_mode_box.h (新設): enum/getter
- CURRENT_TASK.md: Phase ML1 結果記載

## Test Results
| Iterations | ZERO_MODE=full | ZERO_MODE=header | Improvement |
|-----------|----------------|-----------------|------------|
| 10K       | 3.06 M ops/s   | 3.17 M ops/s    | +3.65%     |
| 1M        | 23.71 M ops/s  | 27.34 M ops/s   | **+15.34%** |

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-10 09:08:18 +09:00
parent a905e0ffdd
commit acc64f2438
115 changed files with 2103 additions and 1287 deletions

View File

@ -0,0 +1,120 @@
# ENV Profile Presets (HAKMEM)
よく使う構成を 3 つのプリセットにまとめました。まずここからコピペし、必要な ENV だけを追加してください。v2 系や LEGACY 専用オプションは明示 opt-in で扱います。
ベンチバイナリでは `HAKMEM_PROFILE=<名前>` をセットすると、ここで定義した ENV を自動で注入します(既に設定済みの ENV は上書きしません)。
---
## Profile 1: MIXED_TINYV3_C7_SAFE標準 Mixed 161024B
### 目的
- Mixed 161024B の標準ベンチ用。
- C7-only SmallObject v3 + Tiny front v3 + LUT + fast classify ON。
- Tiny/Pool v2 はすべて OFF。
### ENV 最小セットRelease
```sh
HAKMEM_BENCH_MIN_SIZE=16
HAKMEM_BENCH_MAX_SIZE=1024
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_TINY_FRONT_V3_ENABLED=1
HAKMEM_TINY_FRONT_V3_LUT_ENABLED=1
HAKMEM_TINY_PTR_FAST_CLASSIFY_ENABLED=1
HAKMEM_FREE_POLICY=batch
HAKMEM_THP=auto
```
### 任意オプション
- stats を見たいとき:
```sh
HAKMEM_TINY_HEAP_STATS=1
HAKMEM_TINY_HEAP_STATS_DUMP=1
HAKMEM_SMALL_HEAP_V3_STATS=1
```
- v2 系は触らないC7_SAFE では Pool v2 / Tiny v2 は常時 OFF
- vm.max_map_count が厳しい環境で Fail-Fast を避けたいときの応急処置(性能はほぼ同等〜微減):
```sh
HAKMEM_FREE_POLICY=keep
HAKMEM_DISABLE_BATCH=1
HAKMEM_SS_MADVISE_STRICT=0
```
---
## Profile 2: C6_HEAVY_LEGACY_POOLV1mid/smallmid C6-heavy ベンチ)
### 目的
- C6-heavy mid/smallmid のベンチ用。
- C6 は v1 固定C6 v3 OFF、Pool v2 OFF。Pool v1 flatten は bench 用に opt-in。
### ENVv1 基準線)
```sh
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
HAKMEM_TINY_HEAP_PROFILE=C7_SAFE
HAKMEM_TINY_C6_HOT=1
HAKMEM_TINY_HOTHEAP_V2=0
HAKMEM_SMALL_HEAP_V3_ENABLED=1
HAKMEM_SMALL_HEAP_V3_CLASSES=0x80 # C7-only v3, C6 v3 は OFF
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_POOL_V1_FLATTEN_ENABLED=0 # flatten は初回 OFF
```
### Pool v1 flatten A/B 用LEGACY 専用)
```sh
# LEGACY + flatten ON (研究/bench専用)
HAKMEM_TINY_HEAP_PROFILE=LEGACY
HAKMEM_POOL_V2_ENABLED=0
HAKMEM_POOL_V1_FLATTEN_ENABLED=1
HAKMEM_POOL_V1_FLATTEN_STATS=1
```
- flatten は LEGACY 専用。C7_SAFE / C7_ULTRA_BENCH ではコード側で強制 OFF になる前提。
---
## Profile 3: DEBUG_TINY_FRONT_PERFperf 用 DEBUG プロファイル)
### 目的
- Tiny front v3C7 v3 含む)の perf record 用。
- -O0 / -g / LTO OFF でシンボル付き計測。
### ビルド例
```sh
make clean
CFLAGS='-O0 -g' USE_LTO=0 OPT_LEVEL=0 NATIVE=0 \
make bench_random_mixed_hakmem -j4
```
### ENV
```sh
HAKMEM_BENCH_MIN_SIZE=16
HAKMEM_BENCH_MAX_SIZE=1024
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_TINY_FRONT_V3_ENABLED=1
HAKMEM_TINY_FRONT_V3_LUT_ENABLED=1
HAKMEM_TINY_PTR_FAST_CLASSIFY_ENABLED=1
```
### perf 例
```sh
perf record -F 5000 --call-graph dwarf -e cycles:u \
-o perf.data.tiny_front_tf3 \
./bench_random_mixed_hakmem 1000000 400 1
```
- perf 計測時はログを極力 OFF、ENV は MIXED_TINYV3_C7_SAFE をベースにする。
---
### 共通注意
- プリセットから外れて単発の ENV を積み足すと再現が難しくなるので、まずは上記いずれかからスタートし、変更点を必ずメモしてください。
- v2 系Pool v2 / Tiny v2はベンチごとに opt-in。不要なら常に 0。

View File

@ -28,6 +28,23 @@ SmallObject HotBox v3 Design (Tiny + mid/smallmid 統合案)
- Route: `tiny_route_env_box.h``TINY_ROUTE_SMALL_HEAP_V3` を追加。クラスビットが立っているときだけ route snapshot で v3 に振り分け。
- Front: malloc/free で v3 route を試し、失敗時は v2/v1/legacy に落とす直線パス。デフォルトは OFF なので挙動は従来通り。
### Phase S1: C6 v3 研究箱C7 を壊さずにベンチ限定で解禁)
- Gate: `HAKMEM_SMALL_HEAP_V3_ENABLED`/`CLASSES` の bit7=C7デフォルト ON=0x80、bit6=C6research-only、デフォルト OFF。C6 を叩くときは `HAKMEM_TINY_C6_HOT=1` を併用して tiny front を確実に通す。
- Cold IF: `smallobject_cold_iface_v1.h` を C6 にも適用し、`tiny_heap_prepare_page`/`page_becomes_empty` を C7 と同じ形で使う。v3 stats に `page_of_fail` を追加し、free 側の page_of ミスを計測。
- Bench (Release, Tiny/Pool v2 OFF, ws=400, iters=1M):
- C6-heavy A/B: `MIN_SIZE=257 MAX_SIZE=768``CLASSES=0x80`C6 v1**47.71M ops/s**`CLASSES=0x40`C6 v3, stats ON**36.77M ops/s**cls6 `route_hits=266,930 alloc_refill=5 fb_v1=0 page_of_fail=0`。v3 は約 -23%。
- Mixed 161024B: `CLASSES=0x80`C7-only**47.45M ops/s**`CLASSES=0xC0`C6+C7 v3, stats ON**44.45M ops/s**cls6 `route_hits=137,307 alloc_refill=1 fb_v1=0 page_of_fail=0` / cls7 `alloc_refill=2,446`)。約 -6%。
- 運用方針: 標準プロファイルは `HAKMEM_SMALL_HEAP_V3_CLASSES=0x80`C7-only v3に確定。C6 v3 は bench/研究のみ明示 opt-in とし、C6-heavy/Mixed の本線には乗せない。性能が盛り返すまで研究箱据え置き。
- C6-heavy を v1 固定で走らせる推奨プリセット(研究と混同しないための明示例):
```
HAKMEM_BENCH_MIN_SIZE=257
HAKMEM_BENCH_MAX_SIZE=768
HAKMEM_TINY_HEAP_PROFILE=C7_SAFE
HAKMEM_TINY_C6_HOT=1
HAKMEM_SMALL_HEAP_V3_ENABLED=1
HAKMEM_SMALL_HEAP_V3_CLASSES=0x80 # C7-only v3
```
設計ゴール (SmallObjectHotBox v3)
---------------------------------
- 対象サイズ帯:

View File

@ -64,6 +64,23 @@
- route/guard 判定unified_cache_enabled / tiny_guard_is_enabled / classify_ptrが合わせて ~6% 程度。
- 次は「size→class→route 前段header」をフラット化するターゲットが有力。
## TF3 事前計測DEBUGシンボル, front v3+LUT ON, C7-only v3
環境: `HAKMEM_BENCH_MIN_SIZE=16 HAKMEM_BENCH_MAX_SIZE=1024 HAKMEM_TINY_HEAP_PROFILE=C7_SAFE HAKMEM_TINY_C7_HOT=1 HAKMEM_TINY_HOTHEAP_V2=0 HAKMEM_POOL_V2_ENABLED=0 HAKMEM_SMALL_HEAP_V3_ENABLED=1 HAKMEM_SMALL_HEAP_V3_CLASSES=0x80 HAKMEM_TINY_FRONT_V3_ENABLED=1 HAKMEM_TINY_FRONT_V3_LUT_ENABLED=1`
ビルド: `BUILD_FLAVOR=debug OPT_LEVEL=0 USE_LTO=0 EXTRA_CFLAGS=-g`
ベンチ: `perf record -F5000 --call-graph dwarf -e cycles:u -o perf.data.tiny_front_tf3 ./bench_random_mixed_hakmem 1000000 400 1`
Throughput: **12.39M ops/s**DEBUG/-O0 相当)
- `ss_map_lookup`: **7.3% self**free 側での ptr→SuperSlab 判定が主、C7 v3 でも多い)
- `hak_super_lookup`: **4.0% self**lookup fallback 分)
- `classify_ptr`: **0.64% self**free の入口 size→class 判定)
- `mid_desc_lookup`: **0.43% self**mid 経路の記述子検索)
- そのほか: free/malloc/main が約 30% 強、header write 系は今回のデバッグログに埋もれて確認できず。
所感:
- front v3 + LUT ON でも free 側の `ss_map_lookup` / `hak_super_lookup` が ~11% 程度残っており、ここを FAST classify で直叩きする余地が大きい。
- `classify_ptr` は 1% 未満だが、`ss_map_lookup` とセットで落とせれば +5〜10% の目標に寄せられる見込み。
### Front v3 snapshot 導入メモ
- `TinyFrontV3Snapshot` を追加し、`unified_cache_on / tiny_guard_on / header_mode` を 1 回だけキャッシュする経路を front v3 ON 時に通すようにした(デフォルト OFF
- Mixed 161024B (ws=400, iters=1M, C7 v3 ON, Tiny/Pool v2 OFF) で挙動変化なしslow=1 維持)。ホットスポットは依然 front 前段 (`tiny_region_id_write_header`, `ss_map_lookup`, guard/route 判定) が中心。
@ -82,3 +99,11 @@
- header_v3=0: 44.29M ops/s, C7_PAGE_STATS prepare_calls=2446
- header_v3=1 + SKIP_C7=1: 43.68M ops/s約 -1.4%、prepare_calls=2446、fallback/page_of_fail=0
- 所感: C7 v3 のヘッダ簡略だけでは perf 改善は見えず。free 側のヘッダ依存を落とす or header light/off を別箱で検討する必要あり。
## TF3: ptr fast classify 実装後の A/BC7-only v3, front v3+LUT ON
- Releaseビルド, ws=400, iters=1M, ENV は TF3 基準 (`C7_SAFE`, C7_HOT=1, v2/pool v2=0, v3 classes=0x80, front v3/LUT ON)。
- Throughput (ops/s):
- PTR_FAST_CLASSIFY=0: **33.91M**
- PTR_FAST_CLASSIFY=1: **36.67M**(約 +8.1%
- DEBUG perf同ENV, gate=1, cycles@5k, dwarf: `ss_map_lookup` self が **7.3% → 0.9%**`hak_super_lookup` はトップから消失。代わりに TLS 内のページ判定 (`smallobject_hotbox_v3_can_own_c7` / `so_page_of`) が合計 ~5.5% へ移動。`classify_ptr` は 23% まで微増(外れ時のフォールバック分)。
- 所感: C7 v3 free の Superslab lookup 往復をほぼ除去でき、目標の +5〜10% に収まる結果。fast path 判定の TLS 走査が新たなホットスポットだが、現状コストは lookup より低く許容範囲。