mcpField
P
pgo

pgo

github.com/mohitmishra786開発269575 回インストール18 週間前に更新
リポジトリ

pgo について

PGO は、GCC と Clang のプロファイルガイド最適化や BOLT の手順をエージェントに案内するスキルです。ワークロードの計測からビルド設定、効果の検証まで扱います。

主な機能

  1. 01GCC と Clang の PGO 手順
  2. 02Clang SamplePGO による計測
  3. 03CMake の PGO 設定
  4. 04BOLT によるリンク後最適化
  5. 05プロファイル最適化の効果検証

活用シーン

  1. 01ワークロードに PGO が適するか判断
  2. 02計測用バイナリのビルド
  3. 03perf を使った SamplePGO の設定
  4. 04ベースラインと最適化ビルドの比較

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill pgo

インストール後、Claude Code で/pgoを入力して読み込まれたか確認します。

同梱ファイルreferences/pgo-workflow.md

詳細

PGO(プロファイル誘導最適化)

目的

GCC と Clang の両方に加え、リンク後の最適化に使う BOLT も含め、計測用ビルド → 代表的なワークロードの実行 → プロファイルの収集 → 最適化ビルドという PGO の全ワークフローをエージェントに案内します。

トリガー

  • 「PGO を使ってバイナリを高速化するにはどうすればよいですか?」
  • 「プロファイル誘導最適化とは何ですか? いつ使うべきですか?」
  • 「-fprofile-generate と -fprofile-use はどのように使いますか?」
  • 「-O3 でビルドしても十分な速さが出ません。次に何をすればよいですか?」
  • 「BOLT は PGO とどう違いますか?」
  • 「代表的なプロファイルデータを収集するにはどうすればよいですか?」

ワークフロー

1. PGO を使うタイミング
Is -O3 -march=native already applied?
  no  → apply standard optimisation first
  yes → is workload branch-heavy or has irregular call patterns?
          yes → PGO will likely help 5-30%
          no  → PGO may not help; profile first with linux-perf

PGO は、次のような場合に最も効果を発揮します。

  • 実行頻度の低いコードパスと高いコードパスが多数ある大規模なバイナリ(コンパイラー、データベース、サーバーなど)
  • 静的予測が外れる、分岐の多いコード
  • プロファイルデータを使うことでインライン化の判断が改善する、関数呼び出しの多いコード
2. GCC の PGO ワークフロー
# Step 1: Build with instrumentation
gcc -O2 -fprofile-generate -fprofile-dir=./pgo-data \
    prog.c -o prog_instr

# Step 2: Run with representative workload(s)
./prog_instr < workload1.input
./prog_instr < workload2.input
# Generates .gcda files in ./pgo-data/

# Step 3: Build optimised binary using profile
gcc -O2 -fprofile-use -fprofile-dir=./pgo-data \
    -fprofile-correction \
    prog.c -o prog_pgo

-fprofile-correction は、並列実行や非決定的な実行によって生じるプロファイルカウントの不整合に対処します。必ず指定してください。

3. Clang の PGO ワークフロー(IR ベース、推奨)
# Step 1: Instrument build
clang -O2 -fprofile-instr-generate prog.c -o prog_instr

# Step 2: Run workload (generates default.profraw)
./prog_instr < workload.input
LLVM_PROFILE_FILE="prog-%p.profraw" ./prog_instr  # per-PID files for parallel runs

# Step 3: Merge raw profiles
llvm-profdata merge -output=prog.profdata *.profraw

# Step 4: Optimised build
clang -O2 -fprofile-instr-use=prog.profdata prog.c -o prog_pgo

Clang の IR PGO は GCC より正確で、計測のオーバーヘッドがないサンプリングベースの SamplePGO もサポートしています。

4. Clang SamplePGO(サンプリング、計測なし)
# Step 1: Build with frame pointers for accurate stacks
clang -O2 -fno-omit-frame-pointer prog.c -o prog

# Step 2: Sample with perf
perf record -b -e cycles:u ./prog < workload.input
perf script -F ip,brstack > perf.script  # or use perf2bolt

# Step 3: Convert perf data
llvm-profgen --binary=./prog --perf-script=perf.script \
             --output=prog.profdata

# Step 4: Optimised build
clang -O2 -fprofile-sample-use=prog.profdata prog.c -o prog_spgo

SamplePGO は、計測のオーバーヘッドなしで本番環境のプロファイリングを行うのに最適です。

5. CMake との統合
option(PGO_INSTRUMENT "Build with PGO instrumentation" OFF)
option(PGO_USE "Build with PGO profile data" OFF)

if(PGO_INSTRUMENT)
    add_compile_options(-fprofile-instr-generate)
    add_link_options(-fprofile-instr-generate)
endif()

if(PGO_USE)
    add_compile_options(-fprofile-instr-use=${CMAKE_SOURCE_DIR}/prog.profdata)
    add_link_options(-fprofile-instr-use=${CMAKE_SOURCE_DIR}/prog.profdata)
endif()

ビルドスクリプト:

# Phase 1: instrument
cmake -S . -B build-pgo-instr -DPGO_INSTRUMENT=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build-pgo-instr -j$(nproc)

# Collect profile
./build-pgo-instr/prog < workload.input
llvm-profdata merge -output=prog.profdata *.profraw

# Phase 2: optimised
cmake -S . -B build-pgo -DPGO_USE=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build-pgo -j$(nproc)
6. BOLT(リンク後のバイナリ最適化)

BOLT は、プロファイルデータに基づいて最終バイナリ内の関数と基本ブロックの順序を変更し、命令キャッシュの局所性を向上させます。PGO の後に適用すると、さらに 5~15% の改善が見込めます。

# Step 1: Build with relocation support
clang -O2 -Wl,--emit-relocs prog.c -o prog

# Step 2: Collect profile with perf
perf record -e cycles:u -b ./prog < workload.input
perf2bolt prog -p perf.data -o prog.fdata

# Or use instrumented BOLT
llvm-bolt prog -instrument -o prog.instr
./prog.instr < workload.input
# Generates /tmp/prof.fdata

# Step 3: Apply BOLT optimisation
llvm-bolt prog -data prog.fdata -o prog.bolt \
    -reorder-blocks=ext-tsp \
    -reorder-functions=hfsort \
    -split-functions \
    -split-all-cold \
    -dyno-stats
7. PGO の効果を検証する
# Compare perf of instrumented vs PGO build
perf stat ./prog_baseline < workload.input
perf stat ./prog_pgo < workload.input

# Check which functions are hot in each
perf record ./prog_pgo < workload.input
perf report --stdio | head -30

ワークフローの詳細と、Clang と GCC のプロファイル形式に関する注意事項については、references/pgo-workflow.md を参照してください。

関連スキル

  • GCC のフラグの背景については skills/compilers/gcc を使用してください
  • Clang の PGO と SamplePGO の設定については skills/compilers/clang を使用してください
  • SamplePGO 用の perf データを収集するには skills/profilers/linux-perf を使用してください
  • PGO を適用する前にホットパスを特定するには skills/profilers/flamegraphs を使用してください

コメント