Files
hakmem/PHASE_ML1_CHATGPT_GUIDE.md
Moe Charm (CI) acc64f2438 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>
2025-12-10 09:08:18 +09:00

3.5 KiB
Raw Blame History

PHASE ML1: ChatGPT 依頼用ガイドPool v1 memset 89.73% 課題)

1. 背景情報

  • mid/smallmid (C6-heavy, Pool v1/flatten 系) のベンチで __memset_avx2_unaligned_erms が self 89.73% を占有perf 実測)。
  • 目的: Pool v1 の zero コストを減らす(デフォルト安全は維持しつつ、ベンチ専用の opt-in を用意)。
  • 現状: zero mode を pool_api.inc.h に直接足したところ、ベンチ起動直後にセグフォが発生。

2. 問題の詳細

  • セグフォの推測要因
    • pool_api.inc.h が複数翻訳単位から include され、static キャッシュ変数が TU ごとにばらける。
    • ENV 読み取りをヘッダ内で直接行ったため、初期化順や再定義が崩れている可能性。
    • ZERO_MODE=header 実装が TLS/flatten 経路と食い違っているかもしれない。
  • 現在のコード(問題箇所のイメージ)
    • HAKMEM_POOL_ZERO_MODE をヘッダ内で static int g=-1; getenv(...); する小さな関数を追加しただけで segfault。

3. 修正案2択

  • 選択肢 A: Environment Cache を使う(推奨)
    • core/hakmem_env_cache.h など既存の ENV キャッシュ箱に「pool_zero_mode」を追加し、ヘッダ側は薄い getter だけにする。
    • 1 箇所で getenv/パース → 全翻訳単位で一貫させる(箱理論: 変換点を 1 箇所に)。
  • 選択肢 B: 制約を緩和(暫定)
    • ヘッダで ENV を読まない。zero/partial memset を呼ぶかどうかを、C 側の単一関数で判定して呼び出すだけに戻す。
    • まずセグフォを解消し、memset の最適化は後続フェーズに送る。

4. 詳細な調査手順

  • memset 呼び出し元の再確認
    rg \"memset\" core/hakmem_pool.c core/box/pool_api.inc.h
    
  • perf の再取得C6-heavy LEGACY/flatten なし)
    export HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1
    perf record -F 5000 --call-graph dwarf -e cycles:u -o perf.data.ml1 \
      ./bench_mid_large_mt_hakmem 1 1000000 400 1
    perf report -i perf.data.ml1 --stdio | rg memset
    perf annotate -i perf.data.ml1 __memset_avx2_unaligned_erms | head -40
    
  • 呼び出し階層を掘るTLS alloc か slow path かを確認)
    perf script -i perf.data.ml1 --call-trace | rg -C2 'memset'
    

5. 実装の方向性の再検討

  • TLS alloc path で memset が本当に呼ばれているかを必ず確認(hak_pool_try_alloc_v1_flat 周辺)。
  • memset が page 初期化のみなら、ZERO_MODE は TLS ring には効かない可能性 → 方針を「page 初期化の頻度を減らす」に切替も検討。
  • ZERO_MODE を入れる場合も:
    • ENV キャッシュを 1 箇所に集約。
    • デフォルトは FULL zero、header/off は bench opt-in。
    • Fail-Fast: 異常 ENV はログして既定値にフォールバック。

6. テストコマンドA/B

# ベースラインFULL zero
export HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1
timeout 120 ./bench_mid_large_mt_hakmem 1 1000000 400 1

# header modememset を軽量化する実装を入れたら)
export HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1
export HAKMEM_POOL_ZERO_MODE=header
timeout 120 ./bench_mid_large_mt_hakmem 1 1000000 400 1
  • 比較: ops/s, SS/POOL statsあれば memset 呼び出し数 proxy、セグフォ/アサートがないこと。
  • header mode で +3〜5% 程度伸びれば成功。負になれば撤回 or slow-path のみに適用。