hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

perf topコマンドの使い方



1 perf topコマンドとは?

perfコマンドはLinuxのパフォーマンス分析に使用します。perfコマンドには多くのサブコマンドが含まれており、その中でtopサブコマンドは主にパフォーマンス解析やトラブルシューティングのために利用します。なお、manページではこれらのサブコマンドを「コマンド」と表現していますが、混同を避けるため、この記事では「サブコマンド」と呼ぶことにします。

2 検証環境

AlmaLinux版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
AlmaLinux release 9.2 (Turquoise Kodkod)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
5.14.0-284.11.1.el9_2.x86_64

3 インストール方法

perfパッケージをインストールします。

[root@server ~]# dnf -y install perf

perfコマンドの版数を確認します。

[root@server ~]# perf -v
perf version 5.14.0-284.30.1.el9_2.x86_64

4 コマンド一覧

perfコマンドには、以下のサブコマンドがあります。

[root@server ~]# perf -h

 usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS]

 The most commonly used perf commands are:
   annotate        Read perf.data (created by perf record) and display annotated code
   archive         Create archive with object files with build-ids found in perf.data file
   bench           General framework for benchmark suites
   buildid-cache   Manage build-id cache.
   buildid-list    List the buildids in a perf.data file
   c2c             Shared Data C2C/HITM Analyzer.
   config          Get and set variables in a configuration file.
   daemon          Run record sessions on background
   data            Data file related processing
   diff            Read perf.data files and display the differential profile
   evlist          List the event names in a perf.data file
   ftrace          simple wrapper for kernel's ftrace functionality
   inject          Filter to augment the events stream with additional information
   iostat          Show I/O performance metrics
   kallsyms        Searches running kernel for symbols
   kmem            Tool to trace/measure kernel memory properties
   kvm             Tool to trace/measure kvm guest os
   kwork           Tool to trace/measure kernel work properties (latencies)
   list            List all symbolic event types
   lock            Analyze lock events
   mem             Profile memory accesses
   record          Run a command and record its profile into perf.data
   report          Read perf.data (created by perf record) and display the profile
   sched           Tool to trace/measure scheduler properties (latencies)
   script          Read perf.data (created by perf record) and display trace output
   stat            Run a command and gather performance counter statistics
   test            Runs sanity tests.
   timechart       Tool to visualize total system behavior during a workload
   top             System profiling tool.
   version         display the version of perf binary
   probe           Define new dynamic tracepoints
   trace           strace inspired tool

 See 'perf help COMMAND' for more information on a specific command.

各サブコマンド(COMMAND)のヘルプは、以下の書式にしたがって表示します。

perf help COMMAND

topサブコマンドのヘルプを表示してみます。

[root@server ~]# perf help top
PERF-TOP(1)                                          perf Manual                                          PERF-TOP(1)

NAME
       perf-top - System profiling tool.

SYNOPSIS
       perf top [-e <EVENT> | --event=EVENT] [<options>]

DESCRIPTION
       This command generates and displays a performance counter profile in real time.

OPTIONS
       -a, --all-cpus
           System-wide collection. (default)
-snip-

5 テストプログラムの作成

perf topコマンドでCPU使用率等を確認するため、テストプログラムを作成します。

[root@server ~]# vi test.c
[root@server ~]# cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define COUNT 1000000

void func11() {}
void func22() {}

void func1()
{
    for (int i = 0; i < COUNT; i++) {
            func11();
    }
    usleep(1000);  // 1ミリ秒のスリープ
}

void func2()
{
    for (int i = 0; i < COUNT; i++) {
            func22();
    }
    usleep(1000);  // 1ミリ秒のスリープ
}

int main()
{
    srand(time(NULL));
    while (1) {
        int random = rand() % 5; // 0から4の乱数を生成

        if (random == 0) {
            func2(); // 20%の確率でfunc2を呼び出す
        } else {
            func1(); // 80%の確率でfunc1を呼び出す
        }
    }
    return 0; // この部分には到達しない
}

テストプログラムをコンパイルします。

[root@server ~]# gcc -g -Wall -o test test.c

6 基本的な使い方

perfコマンドに続けて、topサブコマンドを指定します。終了するには、Ctrl+cを押下します。

[root@server ~]# perf top

実行結果は以下のようになります。各列の意味は以下のとおりです。

列の名前 意味
Overhead 関数またはプロセスが使用している CPU の割合を表しています
Shared Object プログラムまたはライブラリー名を表しています
Symbol [k]はカーネル空間で実行する関数、[.]はユーザ空間で実行する関数を表しています

tasksetコマンドを使って、テストプログムをCPU0で実行します。なお、tasksetコマンドの使い方は、tasksetコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# taskset -c 0 ./test &
[1] 2713

psコマンドを使用して、プロセスの状態を確認します。testプロセスはCPU0(CPU使用率73%程度)で動作していることがわかります。なお、psコマンドの使い方は、psコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# ps -C test -o comm,pid,ppid,psr,%cpu
COMMAND             PID    PPID PSR %CPU
test               2713    2587   0 72.7

perf topの実行結果を確認すると、testプログラムの関数が表示されていることがわかります。

7 モニタするCPUを指定する方法(-C)

lscpuコマンドを実行して、マシンに搭載されているCPU数を確認すると、4つあることがわかります。なお、lscpuコマンドの使い方は、lscpuコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# lscpu -ae
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
  0    0      0    0 0:0:0:0          yes
  1    0      1    1 2:2:2:2          yes
  2    0      2    2 4:4:4:4          yes
  3    0      3    3 6:6:6:6          yes

perf topコマンドを実行します。このとき、CPU0で実行している関数名だけを表示するようにします。

[root@server ~]# perf top -C 0

実行結果を確認すると、CPU0で動作しているtestプロセスが表示されていることがわかります。

次に、CPU1,2,3で実行しているプロセスだけを表示するようにします。

[root@server ~]# perf top -C 1,3

実行結果を確認すると、testプロセスが表示されていないことがわかります。

8 カーネルモードで実行している関数を表示する方法(-U)

-Uオプションは、カーネルモードで実行している関数だけを表示するオプションです。

[root@server ~]# perf top -U

実行結果を確認すると、シンボル列が[K]となっているので、カーネルモードで実行している関数だけが表示されていることがわかります。

9 ユーザモードで実行している関数を方法(-K)

-Kオプションは、ユーザモードで実行している関数だけを表示するオプションです。

[root@server ~]# perf top -K

実行結果を確認すると、シンボル列が[.]となっているので、ユーザモードで実行している関数だけが表示されていることがわかります。

10 表示間隔を変更する方法(-d)

-dオプションは、表示間隔を指定するオプションです。以下のように実行すると、情報が10秒ごとに更新されます。

[root@server ~]# perf top -d 10

11 特定の情報を表示する方法(--sort)

commオプションは、コマンド列を表示するオプションです。

[root@server ~]# perf top --sort comm

実行結果を確認すると、コマンド列が表示されていることがわかります。コマンド列と言っていますが、表示しているのはプロセス名です。

pidオプションは、プロセスID(PID)列を表示するオプションです。commオプションとあわせて指定してみます。

[root@server ~]# perf top --sort comm,pid

実行結果を確認すると、コマンド列とPID列が表示されていることがわかります。testプロセスのPIDが2713であることがわかります。

cpuオプションは、プロセスを実行しているCPU列を表示するオプションです。comm,pidオプションとあわせて指定してみます。

[root@server ~]# perf top --sort comm,pid,cpu

実行結果を確認すると、コマンド列,PID列,CPU列が表示されていることがわかります。testプロセスはCPU0で動作していることがわかります。

12 関数の呼び出し関係を表示する方法(-g)

-gオプションは、関数の呼び出し関係を表示するオプションです。

[root@server ~]# perf top -g

↑↓キーを使って、詳細表示したい関数にカーソルをあわせて、Enterキーを押下します。

次に「Expand」の行にカーソルをあわせて、Enterキーを押下します。

実行結果を確認すると、次のような関数呼び出しになっていることがわかります。また、それぞれの関数のCPU使用率が表示されていることもわかります。
・__libc_start_call_main -> main -> func1
・func1 -> func11

13 perfコマンドをリアルタイム優先度で実行する方法(-r)

-rオプションは、 perfコマンドをリアルタイムプロセスで実行するオプションです。指定しないとタイムシェアリングプロセスとして実行します。リアルタイムプロセスで実行することで、確実にパフォーマンスデータが取得できる一方で、他のプロセスに与える影響が大きくなります。

オプションを指定しないでperf topを実行します。

[root@server ~]# perf top

psコマンドを使用すると、perfプロセスはタイムシェアリングプロセスとして実行されていることがわかります。なお、psコマンドの使い方は、psコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# ps -C perf -o comm,cls,rtprio
COMMAND         CLS RTPRIO
perf             TS      -

perfコマンド をリアルタイムプロセスの最高優先度(1)で実行します。

[root@server ~]# perf top -r 1

psコマンドを使用すると、perfプロセスはリアルタイムプロセス(優先度1)として実行されていることがわかります。

[root@server ~]# ps -C perf -o comm,cls,rtprio
COMMAND         CLS RTPRIO
perf             FF      1

perfコマンド をリアルタイムプロセスの最低優先度(99)で実行します。

[root@server ~]# perf top -r 99

psコマンドを使用すると、perfプロセスはリアルタイムプロセス(優先度99)として実行されていることがわかります。

[root@server ~]# ps -C perf -o comm,cls,rtprio
COMMAND         CLS RTPRIO
perf             FF     99