最終更新日 2025年1月31日
スポンサーリンクperfコマンドの出力結果の見方
perfコマンドを使ってデータを収集した後、その結果を正しく読み取ることが重要 です。出力結果を理解することで、ボトルネックの特定や最適化の方向性を見極めることができます。
perfコマンドの基本的な使い方は以下の記事で解説してしますのでよかったら見てみてください!
この章では、以下の4つのコマンドの出力結果の見方を詳しく解説します。
perf stat
– システム全体のパフォーマンス指標の解析perf report
– プロファイルデータの詳細な分析perf top
– リアルタイムのCPU使用率解析perf annotate
– コードレベルでの詳細な解析
それぞれの出力結果を実際のデータとともに説明し、よくある質問をQ&A形式で解説します。
スポンサーリンクperf stat
の出力を読み解く
perf stat
は、CPUサイクル、命令数、キャッシュミスなどの指標を取得し、システム全体のパフォーマンスを測定するために使用します。
基本的な使い方
例えば、5秒間システム全体のパフォーマンスを計測するには、以下のように実行します。
perf stat -a sleep 5
perfコマンドのオプションの使い方は以下の記事で説明しているので良かったらみてみてください!
出力例
Performance counter stats for 'system wide':
1,234,567,890 cycles
567,890,123 instructions # 0.46 insn per cycle
12,345,678 cache-misses # 5.1% of all cache refs
3,210,987 context-switches
各項目の意味
項目 | 意味 |
---|---|
cycles | CPUのクロックサイクル数。数が多いほど、長時間CPUが動作している |
instructions | 実行された命令の数。命令数が少ないと、処理効率が悪い可能性がある |
IPC(Instructions Per Cycle) | 1サイクルあたりの命令実行数。値が1.0未満の場合、CPUが待機時間を多く持つ |
cache-misses | キャッシュミスの回数。数値が高いと、メモリアクセスの最適化が必要 |
context-switches | コンテキストスイッチ(プロセス切り替え)の回数。数が多すぎるとオーバーヘッドが発生 |
出力例の見方
① cycles
(サイクル数)
1,234,567,890 cycles
- 意味 cyclesとはCPUが処理を実行する際のクロックサイクル(CPUの動作単位)をカウントしたもの。
- 解釈 数字が大きいほど、プログラムの実行に多くの時間がかかっている可能性がある。
- 補足 CPUの動作周波数(例:3GHz)を使うと、実際の処理時間を推定できる。例えば、3GHzのCPUなら
1,234,567,890 / 3,000,000,000 ≈ 0.41秒
かかったことになる。
② instructions
(命令数)
567,890,123 instructions # 0.46 insn per cycle
- 意味 実行されたCPU命令の総数。
- 解釈 数字が多いほど、多くの命令を処理している。
- 補足
insn per cycle
(IPC、1サイクルあたりの命令数)も表示されており、これはCPUの効率を示す指標。- 0.46 IPC なので、1サイクルあたり 約0.46命令 実行している。
- IPCが 1以上 なら効率が良い、0.5以下 ならボトルネック(処理の遅延)がある可能性がある。
③ cache-misses
(キャッシュミス)
12,345,678 cache-misses # 5.1% of all cache refs
- 意味 CPUがデータをキャッシュから取得できず、メモリ(RAM)へアクセスする回数。
- 解釈 キャッシュミスが多いと、処理速度が低下する可能性がある。
- 補足
5.1%
は全キャッシュアクセスのうち、どのくらいがミスしたかを示す。- 5.1%は少し高め なので、メモリアクセスの最適化(データのアクセスパターンの改善など)が必要かもしれない。
④ context-switches
(コンテキストスイッチ数)
3,210,987 context-switches
- 意味 CPUが実行中のプロセスを切り替えた回数。
- 解釈 高い値だと、タスク切り替え(スケジューリング)によるオーバーヘッド(負荷)が増える。
- 補足
- 値が高すぎる場合 は、マルチタスクの負荷が高く、CPUが頻繁にプロセスを切り替えている可能性がある。
- 理想的には、不要なプロセスを減らしたり、スレッドの管理を最適化すると改善できる。
Q&A perf stat
の出力結果の見方
IPCって何ですか? 0.46という値は良いんでしょうか?
IPC(Instructions Per Cycle)は、CPUの1サイクルあたりに実行される命令の数を表しているよ。理論的には1.0以上が理想だけど、実際にはプログラムの種類によって変わる。0.46なら、CPUが待機している時間が長い可能性があるね。
キャッシュミスが多いと、どういう問題が起きるんですか?
キャッシュミスが多いと、CPUがメモリからデータを取得するのに時間がかかってしまう。プログラムのデータアクセスパターンを見直すと、改善できることが多いよ。
perf report
の出力を分析する
perf record
で収集したプロファイルデータを解析し、どの関数が最もCPUを消費しているのかを確認できます。
基本的な使い方
perf record -g ./my_program
perf report
出力例
# Overhead Command Shared Object Symbol
# ........ ........... .................... ..........................
38.91% my_program my_program_binary [.] compute_heavy_function
12.44% my_program libc.so.6 [.] malloc
8.92% my_program my_program_binary [.] process_data
各項目の意味
項目 | 意味 |
---|---|
Overhead | CPU使用率の割合(どの関数が最も重いか) |
Command | 実行されたプログラム名 |
Shared Object | 実行ファイルやライブラリ名 |
Symbol | 実行された関数名 |
出力例の見方
38.91% my_program my_program_binary [.] compute_heavy_function
compute_heavy_function
という関数が 全体の 38.91% の CPU 時間を消費my_program_binary
というプログラムの中の処理[.]
は通常、自プログラム内の関数を意味する- CPU 負荷の大部分をこの関数が占めているため、最適化の余地がある
12.44% my_program libc.so.6 [.] malloc
malloc
はメモリを確保する標準ライブラリ関数(libc.so.6
に含まれる)- 全体の 12.44% の CPU 時間をメモリ確保が占めている
- メモリ確保の回数が多すぎる可能性があり、改善することで性能向上が期待できる
8.92% my_program my_program_binary [.] process_data
process_data
関数が 8.92% の CPU 時間を消費compute_heavy_function
よりは少ないが、それなりに影響がある
Q&A perf report
の出力結果の見方
この Overhead
って何を意味してるんですか?
CPUの処理時間の何パーセントをその関数が使ったかを示しているよ。上の例だと compute_heavy_function
が 38.91% も使っているから、この関数がボトルネックになっている可能性が高いね。
関数の並び順を変えることはできますか?
--sort
オプションを使うと、並び順を変更できるよ。例えば perf report --sort=cpu
とすると、CPU使用率の高い順に並べ替えられる。
perf top
の出力結果の解釈
perf top
は、リアルタイムでCPUを多く消費している関数を表示します。
perf top
perfコマンドのオプションの使い方は以下の記事で説明しているので良かったらみてみてください!
出力結果の見方は perf report
に似ていますが、リアルタイムデータを表示する点が異なります。
出力例
Samples: 100K of event 'cycles', Event count (approx.): 123456789
Overhead Shared Object Symbol
40.32% my_program_binary [.] compute_heavy_function
15.67% libc.so.6 [.] malloc
9.85% my_program_binary [.] process_data
5.42% libm.so.6 [.] exp
3.21% kernel.vmlinux [k] schedule</code>
各列の意味
列名 | 説明 |
---|---|
Overhead | CPU 使用時間のうち、その関数が占める割合(%) |
Shared Object | 関数が含まれる共有ライブラリやバイナリ |
Symbol | 実行された関数やシンボル名 |
出力例の見方
① compute_heavy_function
(40.32%)
40.32% my_program_binary [.] compute_heavy_function
compute_heavy_function
という関数が 全体の 40.32% の CPU 時間を消費my_program_binary
(自作プログラム)の関数- CPU の大部分を占めているため、最適化の優先度が高い
② malloc
(15.67%)
15.67% libc.so.6 [.] malloc
malloc
は標準ライブラリ(libc.so.6
)の関数で、メモリ確保を行う- 全体の 15.67% の CPU 時間を使用している
malloc
の使用頻度が高すぎる可能性があり、メモリ確保の最適化を考えるべき
③ process_data
(9.85%)
9.85% my_program_binary [.] process_data
process_data
という関数が 9.85% の CPU 時間を消費- ある程度の CPU 負荷がかかっているが、最適化の優先度は
compute_heavy_function
より低い
④ exp
(5.42%)
5.42% libm.so.6 [.] exp
exp
は数学ライブラリ(libm.so.6
)の指数関数- 数学的な計算で CPU を消費している場合、高速な近似アルゴリズムを検討できる
⑤ schedule
(3.21%)
3.21% kernel.vmlinux [k] schedule
[k]
はカーネル内の処理を示すschedule
はプロセスのスケジューリングを行う関数で、CPU のコンテキストスイッチに関連- もし値が高い場合、スレッドの管理やプロセスのスケジューリングを改善するとよい
Q&A perf top
の出力結果の見方
リアルタイムのCPU負荷を見るには top
じゃダメなんですか?
top
はプロセスごとのCPU使用率しか見えないけど、perf top
は関数ごとのCPU使用率をリアルタイムで確認できるのが違いだね。
perf annotate
でコードのどこが遅いかを特定
perf annotate コマンドは、perf record や perf report で収集したプロファイリングデータを アセンブリレベルで詳細に表示 するツールです。
特定の関数(ここでは compute_heavy_function)について、どの命令が どれくらい CPU を消費しているか を調査できます。
perf annotate --symbol=compute_heavy_function
出力例
Percent | Source code & Disassembly
--------+-------------------------------------------------------------------
35.21 | 4005c0: vmulps %xmm1, %xmm0, %xmm0 # 実数のベクトル乗算
8.92 | 4005c4: vaddps %xmm2, %xmm0, %xmm0 # 実数のベクトル加算
5.78 | 4005c8: vmovaps %xmm0, (%rdi) # データのストア
3.12 | 4005cc: callq 400400 <expf> # 指数関数(expf)の呼び出し
2.34 | 4005d0: mov (%rsi), %eax # メモリからデータをロード
各列の意味
列名 | 説明 |
---|---|
Percent | その命令が全体の CPU 使用時間に占める割合(%) |
Address | 命令のメモリアドレス(関数内のオフセット) |
Instruction | 実際のアセンブリ命令 |
Comment | 命令の意味(手動で追加した場合) |
出力例の見方
① vmulps %xmm1, %xmm0, %xmm0
(35.21%)
35.21 | 4005c0: vmulps %xmm1, %xmm0, %xmm0 # 実数のベクトル乗算
vmulps
は SIMD(Single Instruction Multiple Data)命令 で、ベクトル同士の乗算を行う- この命令が全体の 35.21% の CPU 時間を占めているため、ボトルネックになっている
- 最適化のポイント:
- データ配置を工夫してキャッシュヒット率を向上させる
- SIMD の演算を減らせるか検討する
② vaddps %xmm2, %xmm0, %xmm0
(8.92%)
8.92 | 4005c4: vaddps %xmm2, %xmm0, %xmm0 # 実数のベクトル加算
vaddps
は SIMD の加算命令vmulps
の次に大きな CPU 負荷を持つ- 乗算と同様に データの配置や計算の削減 を検討する
③ vmovaps %xmm0, (%rdi)
(5.78%)
5.78 | 4005c8: vmovaps %xmm0, (%rdi) # データのストア
vmovaps
はアライメントされたメモリへのストア命令- ストア操作が高頻度で発生していると、メモリ帯域がボトルネックになる可能性がある
- 可能な最適化:
- キャッシュ効率を向上させる
- 不要なストア命令を削減する
④ callq 400400 <expf>
(3.12%)
3.12 | 4005cc: callq 400400 <expf> # 指数関数(expf)の呼び出し
expf
(指数関数)を呼び出している- 関数呼び出しのオーバーヘッドがある
- 最適化のポイント
- 指数関数の近似計算を使う(例: テイラー展開や LUT(ルックアップテーブル))
- 関数呼び出しを減らす
⑤ mov (%rsi), %eax
(2.34%)
2.34 | 4005d0: mov (%rsi), %eax # メモリからデータをロード
mov
はメモリからレジスタへのデータ転送- メモリアクセスは キャッシュミスが発生すると遅くなる
- 最適化のポイント
- データの局所性を高める(キャッシュに乗るようにする)
- 不要なメモリアクセスを減らす
Q&A perf annotate
の出力結果の見方
アセンブリコードを見ても、どこが問題なのかわからないです……
jmp
や call
の実行回数が多いと、分岐予測ミスが発生している可能性があるね。
ゴリタン
インフラエンジニアとして、ネットワークとサーバーの運用・保守・構築・設計に幅広く携わり、
現在は大規模政府公共データの移行プロジェクトを担当。
CCNPやLPICレベル3、AWSセキュリティスペシャリストなどの資格を保有しています。