---
title: perf の深い活用
url: https://doc.liz6.com/ja/systems-programming/08-performance-and-debugging/01-deep-dive-into-perf
locale: ja
area: systems-programming
tags:
- perf
- linux
- performance
- profiling
- ebpf
- systems-programming
- performance-and-debugging
date: 2026-06-30
modified: 2026-07-16
description: 'カバー範囲: perf record/report/annotate → フレームグラフ → perf stat → PEBS → perf probe → パフォーマンス分析手法'
---

# perf の深い活用

> カバー範囲: perf record/report/annotate → フレームグラフ → perf stat → PEBS → perf probe → パフォーマンス分析手法
> 対象: Linux perf_events (カーネル 2.6.31 以降)

## perf stat: CPU パフォーマンスカウンター

```bash
# カウンタ型: プログラム実行全体を通じたハードウェアイベント
perf stat ls /

# 出力例:
#   task-clock:        # 実際の CPU 時間
#   cycles:            # CPU サイクル (周波数スケーリングの影響を受ける。ユーザー空間のみに制限するには cycles:u を使用)
#   instructions:      # 実行された命令数
#   IPC:               # instructions/cycles (>1 = スーパイプライン利用率が良好)
#   branches:          # ブランチ命令
#   branch-misses:     # ブランチ予測ミス
#   cache-misses:      # キャッシュミス
#   context-switches:  # コンテキストスイッチ
#   page-faults:       # ページフォルト

# 主要指標:
#   IPC < 0.5: 深刻なストール (キャッシュミス、ブランチミス、データ依存性)
#   IPC > 2:   スーパイプラインの高度な利用
#   branch-miss rate > 5%: ブランチ予測の問題
#   cache-miss rate > 10%: データの局所性の問題

# イベントの指定:
perf stat -e cycles,instructions,cache-references,cache-misses,branch-misses ./prog
```

## perf record: サンプリング

```bash
# サンプリング (デフォルト: cycles, サンプリングレート 4000 Hz):
perf record -g ./prog        # -g: コールチェーン（呼び出しグラフ）を記録
perf record -F 99 -g ./prog  # 99 Hz サンプリング (フレームグラフの標準に近い)

# 報告:
perf report                   # インタラクティブ (関数/呼び出しチェーン)
perf report --sort=dso,sym    # .so ファイル + 関数名でソート
perf report -n --stdio        # テキスト形式 + サンプリング数

# アノテーション (ソースコード+アセンブリ+サンプリングの混合):
perf annotate function_name

# リアルタイム top:
perf top -e cycles
```

## フレームグラフ

```bash
# 1. サンプリング:
perf record -F 99 -g -- ./prog

# 2. フレームグラフの生成 (Brendan Gregg のツールを使用):
perf script > out.perf
stackcollapse-perf.pl out.perf > out.folded
flamegraph.pl out.folded > flamegraph.svg

# または 1 行コマンド:
perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg
```

## perf probe: 動的プロービング

```bash
# 任意のユーザー空間関数にプローブポイントを付与:
perf probe -x ./prog my_function
perf probe -x ./prog 'my_function arg1=%di arg2=%si'   # 引数をキャプチャ

# 任意の行にプローブポイントを付与:
perf probe -x ./prog my_file.c:42

# 記録:
perf record -e probe_myprog:my_function -g -- ./prog

# 付与済みのプローブポイントを確認:
perf probe -l

# 削除:
perf probe -d my_function
```

## PEBS: 高精度サンプリング

```bash
# デフォルトのサンプリング: 割り込み後に命令ポインタを読み取る (不正確な場合があり、スキッドが発生する)
# PEBS (Precise Event-Based Sampling): ハードウェアが正確な IP を記録
perf record -e cycles:pp ./prog    # :pp = precise (2レベル)
perf record -e cycles:ppp ./prog   # :ppp = 最も高精度 (ハードウェアサポートが必要)
```

## システムレベル分析

```bash
# システム全体のサンプリング (root 権限が必要):
perf record -a -g -- sleep 10     # 全 CPU、10 秒間

# プロセスでフィルタリング:
perf record -e cycles -p <pid> -- sleep 10
perf record -e cycles -t <tid>    # スレッド単位

# CPU でフィルタリング:
perf record -e cycles -C 0,2 -- sleep 10

# CPU 利用率の分解 (topdown):
perf stat --topdown ./prog        # Intel 第6世代以降
# frontend bound / backend bound / bad speculation / retiring
```

## パフォーマンス分析手法

<svg viewBox="0 0 720 390" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="パフォーマンス分析方法論の意思決定木:まずボトルネックのタイプを推測し、対応する perf コマンドで特定する">
  <defs>
    <marker id="pfah" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker>
  </defs>
  <rect width="720" height="390" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">パフォーマンス分析方法論: まずボトルネックを定性的に特定し、その後段階的に掘り下げる</text>

  <text x="95" y="48" text-anchor="middle" font-size="11" font-weight="600" fill="#64748b">疑われるもの</text>
  <text x="315" y="48" text-anchor="middle" font-size="11" font-weight="600" fill="#64748b">最初に定性分析に使用するもの</text>
  <text x="580" y="48" text-anchor="middle" font-size="11" font-weight="600" fill="#64748b">その後、掘り下げに使用するもの</text>

  <!-- row 1: CPU bound -->
  <rect x="20" y="58" width="150" height="40" rx="8" fill="#4f46e5"/>
  <text x="95" y="83" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">CPU バウンド?</text>
  <line x1="170" y1="78" x2="196" y2="78" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="200" y="58" width="230" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="212" y="83" font-size="11" fill="#115e59">perf stat: IPC / 命令数 / サイクル</text>
  <line x1="430" y1="78" x2="456" y2="78" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="460" y="58" width="240" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="472" y="83" font-size="11" fill="#115e59">perf record: ホットスポット関数の特定</text>

  <!-- row 2: memory bound -->
  <rect x="20" y="114" width="150" height="40" rx="8" fill="#4f46e5"/>
  <text x="95" y="139" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">メモリバウンド?</text>
  <line x1="170" y1="134" x2="196" y2="134" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="200" y="114" width="230" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="212" y="134" font-size="11" fill="#115e59">perf stat: キャッシュミス,</text>
  <text x="212" y="147" font-size="11" fill="#115e59">LLC-loads / LLC-load-misses</text>
  <line x1="430" y1="134" x2="456" y2="134" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="460" y="114" width="240" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="472" y="139" font-size="11" fill="#115e59">perf record -e cache-misses</text>

  <!-- row 3: IO bound -->
  <rect x="20" y="170" width="150" height="40" rx="8" fill="#4f46e5"/>
  <text x="95" y="195" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">I/O バウンド?</text>
  <line x1="170" y1="190" x2="196" y2="190" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="200" y="170" width="230" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="212" y="195" font-size="11" fill="#115e59">iostat / blktrace</text>
  <line x1="430" y1="190" x2="456" y2="190" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="460" y="170" width="240" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="472" y="195" font-size="11" fill="#115e59">perf trace (システムコールと所要時間のトレース)</text>

  <!-- row 4: 競合 -->
  <rect x="20" y="226" width="150" height="40" rx="8" fill="#4f46e5"/>
  <text x="95" y="251" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">ロック競合?</text>
  <line x1="170" y1="246" x2="196" y2="246" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="200" y="226" width="230" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="212" y="251" font-size="11" fill="#115e59">perf lock record + perf lock report</text>
  <line x1="430" y1="246" x2="456" y2="246" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="460" y="226" width="240" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="472" y="251" font-size="11" fill="#115e59">perf stat -e context-switches</text>

  <!-- row 5: ブランチ予測 -->
  <rect x="20" y="282" width="150" height="40" rx="8" fill="#4f46e5"/>
  <text x="95" y="307" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">ブランチ予測?</text>
  <line x1="170" y1="302" x2="196" y2="302" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="200" y="282" width="230" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="212" y="307" font-size="11" fill="#115e59">perf stat -e branch-misses,branches</text>
  <line x1="430" y1="302" x2="456" y2="302" stroke="#475569" stroke-width="1.6" marker-end="url(#pfah)"/>
  <rect x="460" y="282" width="240" height="40" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="472" y="307" font-size="11" fill="#115e59">perf record -e branch-misses</text>

  <!-- insight -->
  <rect x="20" y="336" width="680" height="36" rx="8" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="360" y="358" text-anchor="middle" font-size="12" fill="#3730a3">まず perf stat でボトルネックの種類を定性的に特定し、その後 perf record / trace / lock で具体的な関数や呼び出しポイントまで段階的に掘り下げる。</text>
</svg>

## 参考

- **ドキュメント**: https://perf.wiki.kernel.org, Brendan Gregg's perf examples
- **ツール**: https://github.com/brendangregg/FlameGraph
- **書籍**: "Systems Performance" (Brendan Gregg), "BPF Performance Tools"

*キーワード: perf, PEBS, IPC, cache-misses, flame graph, perf probe, topdown, branch prediction*
