🔥
概念 #システムパフォーマンス #Brendan Gregg #Linux #SRE #読書ノート #perf #フレームグラフ 📚 詳解 システム・パフォーマンス

詳解 システム・パフォーマンス - 第13章:perf

Linux標準プロファイリングツール「perf」の完全レシピ集。CPU프로파일링・フレームグラフ生成・動的トレース・ハードウェアカウンタの実践的な使い方。

perf とは

Linux カーネルに組み込まれた標準のプロファイリング・トレーシングツール
インストール不要(カーネルに含まれる)。カーネル・ユーザー空間の両方を観測できる。

# インストール(Ubuntu/Debian)
sudo apt-get install linux-perf linux-tools-common linux-tools-generic

# インストール(CentOS/RHEL)
sudo yum install perf

# バージョン確認
perf version

perf サブコマンド一覧

サブコマンド用途
perf statCPU ハードウェアカウンタ統計
perf recordCPU サンプリングデータの収集
perf report収集データの分析・表示
perf topリアルタイムの CPU ホットスポット
perf list利用可能なイベント一覧
perf probe動的トレースポイントの追加
perf traceシステムコールトレース(strace 代替)
perf script収集データをテキストで出力
perf ftraceFtrace のラッパー
perf bench組み込みベンチマーク

perf stat:ハードウェアカウンタ

# コマンドの統計を取得
perf stat ls -la

# 実行中のプロセスを測定(10秒)
perf stat -p <PID> sleep 10

# システム全体(10秒)
perf stat -a sleep 10

# 詳細なキャッシュ統計(-d オプション)
perf stat -d -p <PID> sleep 10

# 出力例:
#  10,000,000,000  cycles                    #   3.00 GHz
#   8,000,000,000  instructions              #   0.80  insn per cycle  ← IPC
#     200,000,000  cache-references
#      20,000,000  cache-misses              #  10.00% of all cache refs
#     500,000,000  branches
#       5,000,000  branch-misses             #   1.00% of all branches

# カスタムイベントの指定
perf stat -e cycles,instructions,L1-dcache-loads,L1-dcache-load-misses,\
LLC-loads,LLC-load-misses -p <PID> sleep 10

# 全コア・プロセスごとに分割(-A -p では無効)
perf stat -a -A sleep 5  # コアごとに表示

perf record:CPU プロファイリング

# 基本的なCPUプロファイリング(システム全体、30秒)
sudo perf record -F 99 -a -g sleep 30
# -F 99: 99Hz でサンプリング(100%未満にして干渉を避ける)
# -a: すべての CPU
# -g: コールスタック(グラフ)を記録
# データは ./perf.data に保存される

# 特定プロセス
perf record -F 99 -g -p <PID> sleep 30

# 特定コマンドのプロファイリング
perf record -F 99 -g ./myapp arg1 arg2

# オフCPU分析(I/O・ロック待ち時間の記録)
perf record -e sched:sched_switch -a -g sleep 30

# perf.data のサイズ削減(サンプリング頻度を下げる)
perf record -F 49 -a -g sleep 60

perf report:結果の分析

# インタラクティブな分析
perf report

# キー操作:
# Enter / → : 展開
# ← / q    : 戻る / 終了
# a         : ソースアノテーション(ソースコード行ごとの統計)
# /         : 関数名で検索
# s         : 子孫の統計を表示

# テキスト出力(パイプ処理向け)
perf report --stdio | head -50

# 上位10関数をパーセンテージ付きで表示
perf report --stdio --sort=symbol --no-children | head -20

# 特定の DSO(ライブラリ)にフィルタ
perf report --dsos=libpq.so

フレームグラフの生成(最重要スキル)

手順

# 1. FlameGraph スクリプトをクローン
git clone https://github.com/brendangregg/FlameGraph
cd FlameGraph

# 2. データ収集
sudo perf record -F 99 -a -g -- sleep 60

# 3. スクリプト出力
perf script > /tmp/out.perf

# 4. スタック折り畳み
./stackcollapse-perf.pl /tmp/out.perf > /tmp/out.folded

# 5. SVG 生成
./flamegraph.pl /tmp/out.folded > /tmp/flame.svg

# 2〜5を1行で
sudo perf record -F 99 -a -g -- sleep 60 && \
perf script | ./stackcollapse-perf.pl | \
./flamegraph.pl --title="CPU Profile $(date)" > /tmp/flame.svg && \
echo "Done: /tmp/flame.svg"

フレームグラフのバリエーション

# ホット(赤)カラーパレット(CPU向け)
./flamegraph.pl --colors=hot out.folded > cpu.svg

# ブルーカラー(メモリ向け)
./flamegraph.pl --colors=mem out.folded > mem.svg

# オフCPU フレームグラフ(I/O・ロック待ち)
sudo perf record -e sched:sched_switch -a -g sleep 30
perf script | ./stackcollapse-perf.pl --pid | \
  ./flamegraph.pl --colors=blue --title="Off-CPU Time" > offcpu.svg

# 差分フレームグラフ(チューニング前後の比較)
# チューニング前
perf record -F 99 -a -g sleep 30
perf script | ./stackcollapse-perf.pl > before.folded

# チューニング後
perf record -F 99 -a -g sleep 30
perf script | ./stackcollapse-perf.pl > after.folded

# 差分SVG生成(赤=増加、青=減少)
./difffolded.pl before.folded after.folded | \
  ./flamegraph.pl --title="Diff" > diff.svg

perf top:リアルタイムホットスポット

# システム全体のホットスポット(top に似た見た目)
sudo perf top

# 特定プロセス
perf top -p <PID>

# キー操作:
# s: カラムでソート
# a: アノテーション表示
# z: ゼロカウントの非表示切り替え

# テキスト出力(スクリプト処理向け)
sudo perf top --stdio -n 20 | head -30

perf probe:動的トレース

カーネルやアプリの任意の関数にトレースポイントを追加できる。

# カーネル関数に probe を追加
sudo perf probe --add 'do_sys_open filename:string'

# 追加した probe を確認
perf probe --list

# 収集
sudo perf record -e probe:do_sys_open -aR sleep 10
perf script

# クリーンアップ
sudo perf probe --del '*'

# ユーザー空間の関数(uprobe)
# 例: Python の malloc をトレース
sudo perf probe -x /usr/bin/python3 malloc
sudo perf record -e probe_python3:malloc -aR sleep 5
perf report
sudo perf probe -x /usr/bin/python3 --del malloc

perf trace:システムコールトレース

strace より低オーバーヘッドで syscall をトレース。

# 特定プロセスの syscall トレース
sudo perf trace -p <PID>

# 特定の syscall のみ
sudo perf trace -e read,write,open -p <PID>

# 集計(strace -c に相当)
sudo perf trace -s -p <PID> sleep 10

よくある使用シナリオ

CPU が高い → 原因関数を特定

# 1. プロファイリング
perf record -F 99 -g -p <PID> sleep 30

# 2. 上位関数を確認
perf report --stdio --sort=self --no-children | head -20

# 3. フレームグラフで全体像を見る
perf script | ./FlameGraph/stackcollapse-perf.pl | \
  ./FlameGraph/flamegraph.pl > flame.svg

キャッシュミスが多い → メモリアクセスパターンを確認

# L3 キャッシュミスが多い関数を特定
perf record -e LLC-load-misses -g -p <PID> sleep 30
perf report --stdio | head -30

ロック競合 → 待ち時間を確認

# futex(ロック)の待ち時間をサンプリング
perf record -e 'syscalls:sys_enter_futex' -g -p <PID> sleep 30
perf report

出典: 詳解 システム・パフォーマンス 第2版 Brendan Gregg著