跳转至

perf

  • 官方文档

  • https://www.coonote.com/vim-note/perf-usage.html

1 安装 perf

  • yum安装:yum install -y perf

2 perf 命令

命令 描述
annotate 读取perf.data(由perf record创建)并显示注释过的代码
diff 读取两个perf.data文件并显示两份剖析信息之间的差异
evlist 列出一个perf.data文件里的事件名称
inject 过滤以加强事件流,在其中加入额外的信息
kmem 跟踪/测量内核内存(slab)属性的工具
kvm 跟踪/测量kvm客户机操作系统的工具
list 列出所有的符号事件类型,其中性能事件的包括:Hardware event、Software event、Hardware cache event、tracepoint:Tracepoint event。 Hardware Event 是由 PMU 硬件产生的事件,比如 cache 命中,当您需要了解程序对硬件特性的使用情况时,便需要对这些事件进行采样; Software Event 是内核软件产生的事件,比如进程切换,tick 数等 ; Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数,系统调用,TCP事件,文件系统IO事件,块设备事件等。
lock 分析锁事件
probe 定义新的动态跟踪点
record 运行一个命令,收集采样信息,并把剖析信息记录在perf.data中
report 读取perf.data(由perf record创建)并显示剖析信息
sched 跟踪/测量调度器属性(延时)的工具
script 读取perf.data(由perf record创建)并显示跟踪输出
stat 运行一个命令并收集性能计数器统计信息,用于分析指定程序的性能概况。task-clock:任务真正占用的处理器时间,单位为ms。 context-switches:上下文的切换次数。 CPU-migrations:处理器迁移次数。Linux为了维持多个处理器的负载均衡,在特定条件下会将某个任务从一个CPU迁移到另一个CPU。 page-faults:缺页异常的次数。当应用程序请求的页面尚未建立、请求的页面不在内存中,或者请求的页面虽然在内存中,但物理地址和虚拟地址的映射关系尚未建立时,都会触发一次缺页异常。 cycles:消耗的处理器周期数。 instructions:执行了多少条指令。IPC为平均每个cpu cycle执行了多少条指令。 branches:遇到的分支指令数。branch-misses是预测错误的分支指令数。
timechart 可视化某一个负载期间系统总体性能的工具
top 系统剖析工具。对于一个指定的性能事件(默认是CPU周期),显示消耗最多的函数或指令。perf top类似linux的top命令,可以排列展示当机的函数和指令消耗情况。perf top主要用于实时分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数、模块函数与内核函数,甚至能够定位到热点指令。默认的性能事件为cpu cycles。 结果展示: 第一列:符号引发的性能事件的比例,默认指占用的cpu周期比例。 第二列:符号所在的DSO(Dynamic Shared Object),可以是应用程序、内核、动态链接库、模块。 第三列:DSO的类型。[.]表示此符号属于用户态的ELF文件,包括可执行文件与动态链接库)。[k]表述此符号属于内核或模块。 第四列:符号名。有些符号不能解析为函数名,只能用地址表示。

在命令行使用perf -h可以显示perf支持的命令

[root@centos7 perf_example]# 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.
   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
   kallsyms        Searches running kernel for symbols
   kmem            Tool to trace/measure kernel memory properties
   kvm             Tool to trace/measure kvm guest os
   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.

2.1 perf 通用选项

  • -p, --pid=:指定记录的进程号(只采集此进程数据)(多个用comma分割)
  • -t, --tid=:指定记录的限程号
  • -u, --uid=:指定监控的用户(可以是id,也可以是name)
  • -a, --all-cpu:从所有cpu上采集数据
  • -e, --event= :指定 PMU(处理器监控单元)事件, 事件后可以指定用户态、内核态等
    • -e <event>:u : userspace
    • -e <event>:k : kernel
    • -e <event>:h : hypervisor
    • -e <event>:G :guest counting (in KVM guests)
    • -e <event>:H : host counting (not in KVM guests) `
  • -- sleep time :指定 perf 执行多少秒 (-- 好像不用也可以)

2.2 perf record

  • 功能:运行命令并将其配置文件记录到perf.data中
  • 语法:perf record [-e <EVENT> | --event=EVENT] [-a] — <command> [<options>]
    • -g:启用调用图(堆栈链/回溯)记录
    • --call-graph [fp,dwarf,lbr]:-g选项等价于就是--call-graph fp
      • fp:需要gcc 编译时指定--fomit-frame-pointer
      • dwarf:需要gcc 编译时指定-g(为了更好的显示,一般使用此参数)
      • lbr:需要硬件级cpu支持
    • -F num:记录采样频率
  • 示例:采集指定用户下数据
[root@centos7 perf_example]# perf record -u root -a -g -F 99
Warning:
UID switch overriding SYSTEM
  • 示例:采集执行的命令数据
[root@centos7 perf_example]# perf record  ls
perf.data  perf.data.old  test  test.cc
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.013 MB perf.data (2 samples) ]
  • perf report显示截图

2.3 perf report

  • 功能:从perf.data文件中读取数据,分析并以界面展示
  • 语法:perf report [-i <file> | --input=file]
    • -i file:指定解析的文件(默认是perf.data)
  • 示例
[root@centos7 perf_example]# perf record -g -a ls
1  perf.data  perf.data.old  test  test.cc
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.146 MB perf.data (3 samples) ]
[root@centos7 perf_example]# perf report -g -i perf.data 
  • perf report显示截图

2.4 perf script

  • 功能:从perf.data中读取数据,显示trace输出数据
  • 示例
[root@centos7 perf_example]# perf script

2.5 perf list

  • 功能:显示可用事件
  • 可用事件如下:
事件 功能
hw or hardware 显示硬件事件,比如:cache-misses, etc.
sw or software 显示软件事件,比如:context switches, etc.
cache or hwcache 显示硬件缓存事件,比如:L1-dcache-loads, etc.
tracepoint 显示跟踪点事件, 或者使用subsys_glob:event_glob按跟踪点子系统进行过滤,比如 sched, block, etc.
pmu (Performance Monitoring Unit)显示内核提供的PMU事件
sdt (Statically Defined Tracepoint)显示静态定义跟踪点事件
metric to list metrics(度量指标,比如 cpu、内存、网络、io、存储)
metricgroup to list metricgroups with metrics.

2.6 perf top

  • 功能:实时生成并显示当前系统所有进程函数占用数据
  • 语法:perf top [-e <EVENT> | --event=EVENT] [<options>]

2.7 perf stat

branchs事件 在AMD cpu(amd 5900x测试)上不支持,需要intel cpu
  • 功能:运行命令并收集性能计数器统计信息
  • 语法:perf stat [-e <EVENT> | --event=EVENT] [-a] <command>
    • -C, --cpu= :统计指定的 cpu,默认全部 cpu,格式为 -C 0,1 或者 -C 0-3
    • -G name, --cgroup name :指定cgroup
  • 示例
[root@centos7 perf_example]# perf stat ls
1  perf.data  perf.data.old  test  test.cc

 Performance counter stats for 'ls':

              1.16 msec task-clock                #    0.713 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
               101      page-faults               #    0.087 M/sec                  
   <not supported>      cycles                                                      
   <not supported>      instructions                                                
   <not supported>      branches                                                    
   <not supported>      branch-misses                                               

       0.001629604 seconds time elapsed

       0.001810000 seconds user
       0.000000000 seconds sys
  • 输出列解释:通过指定 -e 选项,可以增加其它事件的统计
事件 功能
Task-clock-msecs CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO
Context-switches 进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的
Cache-misses 程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好
CPU-migrations 表示进程 t1 运行过程中发生了多少次 CPU 迁移,即被调度器从一个 CPU 转移到另外一个 CPU 上运行
Cycles 处理器时钟,一条机器指令可能需要多个 cycles
branches 分支指令数
branch misses 分支预测错误次数
Instructions 机器指令数目
IPC 是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性
Cache-references cache 命中的次数
Cache-misses cache 失效的次数

2.8 perf probe

- `-x` 方式生成的Tracepoint event命令格式:probe_ + 二进制文件名 + : + 函数名
- 添加了新的tracepoints事件后,可以用在record、stat等命令上面(通过-e 指定事件)
  • 功能:定义新的动态tracepoints
  • 语法:perf probe [options]
    • -a, --add=:定义一个新的probe事件
    • -d, --del=:删除一个probe事件
    • -x, --exec=PATH:指定用于用户空间跟踪的可执行文件或共享库文件的路径,添加后可在/sys/kernel/debug/tracing/uprobe_events 文件下查看uprobe事件
  • 示例:将指定可执行文件下函数Tracepoint event
[root@centos7 perf_example]# perf probe -x ./test for_loop
Added new event:
  probe_test:for_loop  (on for_loop in /root/perf_example/test)

You can now use it in all perf tools, such as:

        perf record -e probe_test:for_loop -aR sleep 1
[root@centos7 perf_example]# perf list |grep probe_test:for_loop
  probe_test:for_loop                                [Tracepoint event]
[root@centos7 perf_example]# perf stat -e probe_test:for_loop -ag ./test
pid=2008
^C./test: Interrupt

 Performance counter stats for 'system wide':

                 7      probe_test:for_loop                                         

       4.556302884 seconds time elapsed
[root@centos7 perf_example]# cat /sys/kernel/debug/tracing/uprobe_events 
p:probe_test/for_loop /root/perf_example/test:0x000000000000064d

2.9 perf trace

2.10 perf sched

  • 参考

  • 功能:perf sched 子命令提供了许多用于分析内核 CPU 调度程序行为的工具。
  • 语法:perf sched {record|latency|map|replay|script|timehist}
  • 使用方法 :
    1. 先使用 perf record 产生事件数据,如:perf sched record -- sleep 1
    2. 再使用 perf sched{latency|map|replay|script|timehist} 进行数据分析,如:perf sched timehist

2.10.1 perf sched report

  • 功能:记录任意工作量的调度事件。

2.10.2 perf sched script

  • 作用同 perf script

2.10.3 perf sched latency

title: 什么是调度延迟?为什么会有调度延迟?
- 所谓「调度延迟」,是指一个任务具备运行的条件(进入 CPU 的 runqueue),到真正执行(获得 CPU 的执行权)的这段时间。
- 为什么会有调度延迟呢?因为 CPU 还被其他任务占据,还没有空出来,而且可能还有其他在 runqueue 中排队的任务。
- 排队的任务越多,调度延迟就可能越长,所以这也是间接衡量 CPU 负载的一个指标(CPU 负载通过计算各个时刻 runqueue 上的任务数量获得)。
  • 功能:perf sched latency 将按任务汇总调度程序延迟,包括平均和最大延迟:

2.10.4 perf sched map

  • 功能:perf sched map 显示所有 CPU 和上下文切换事件,其中的列表示每个 CPU 正在做什么以及何时。

2.10.5 perf sched replay

  • 功能:perf sched replay 将获取记录的调度程序事件,然后通过生成具有类似运行时和上下文切换的线程来模拟工作负载。用于测试和开发调度程序更改和配置。不要太相信这个(和其他)工作负载重放器:它们可以是一个有用的负载生成器,但很难完全模拟真实的工作负载。在这里,我使用 -r -1 运行重播,以重复工作负载。

2.10.6 perf sched timehist

  • 功能:(Linux 4.10 新增)按事件显示调度程序延迟,包括任务等待被唤醒的时间(等待时间)和唤醒后运行的调度程序延迟(sch delay)。

2.11 perf mem

  • 功能:分析内存访问
  • 语法:perf mem [<options>] (record [<command>] | report)

2.12 perf lock

需要内核编译开启CONFIG_LOCKDEP 和 CONFIG_LOCK_STAT
  • 功能:分析各种锁定(内核锁)行为和统计信息。
  • 语法:perf lock {record|report|script|info}

2.12.1 perf lock record

  • 语法:perf lock record <command>,如 perf lock record ls

2.12.2 perf lock report

2.12.3 perf lock script

2.12.4 perf lock info

2.13 perf iostat

  • 详见 man 手册
PERF-IOSTAT(1)                                                                                       perf Manual                                                                                      PERF-IOSTAT(1)

NAME
       perf-iostat - Show I/O performance metrics

SYNOPSIS
       perf iostat list
       perf iostat <ports>  <command> [<options>]

DESCRIPTION
       Mode is intended to provide four I/O performance metrics per each PCIe root port:

          Inbound Read - I/O devices below root port read from the host memory, in MB

          Inbound Write - I/O devices below root port write to the host memory, in MB

          Outbound Read - CPU reads from I/O devices below root port, in MB

          Outbound Write - CPU writes to I/O devices below root port, in MB

OPTIONS
       <command>...
           Any command you can specify in a shell.

       list
           List all PCIe root ports.

       <ports>
           Select the root ports for monitoring. Comma-separated list is supported.
  • 示例
EXAMPLES
        1. List all PCIe root ports (example for 2-S platform):

               $ perf iostat list
               S0-uncore_iio_0<0000:00>
               S1-uncore_iio_0<0000:80>
               S0-uncore_iio_1<0000:17>
               S1-uncore_iio_1<0000:85>
               S0-uncore_iio_2<0000:3a>
               S1-uncore_iio_2<0000:ae>
               S0-uncore_iio_3<0000:5d>
               S1-uncore_iio_3<0000:d7>

        2. Collect metrics for all PCIe root ports:

               $ perf iostat -- dd if=/dev/zero of=/dev/nvme0n1 bs=1M oflag=direct
               357708+0 records in
               357707+0 records out
               375083606016 bytes (375 GB, 349 GiB) copied, 215.974 s, 1.7 GB/s

               Performance counter stats for 'system wide':

                  port             Inbound Read(MB)    Inbound Write(MB)    Outbound Read(MB)   Outbound Write(MB)
               0000:00                    1                    0                    2                    3
               0000:80                    0                    0                    0                    0
               0000:17               352552                   43                    0                   21
               0000:85                    0                    0                    0                    0
               0000:3a                    3                    0                    0                    0
               0000:ae                    0                    0                    0                    0
               0000:5d                    0                    0                    0                    0
               0000:d7                    0                    0                    0                    0

        3. Collect metrics for comma-separated list of PCIe root ports:

               $ perf iostat 0000:17,0:3a -- dd if=/dev/zero of=/dev/nvme0n1 bs=1M oflag=direct
               357708+0 records in
               357707+0 records out
               375083606016 bytes (375 GB, 349 GiB) copied, 197.08 s, 1.9 GB/s

               Performance counter stats for 'system wide':

                  port             Inbound Read(MB)    Inbound Write(MB)    Outbound Read(MB)   Outbound Write(MB)
               0000:17               358559                   44                    0                   22
               0000:3a                    3                    2                    0                    0

               197.081983474 seconds time elapsed

2.14 测试代码

  • 编译:g++ test.cc -o test
// test.cc
#include <cmath>
#include <stdio.h>
#include <unistd.h>
void for_loop()
{
    for (int i = 0; i < 1000; i++)
    {
        for (int j = 0; j < 10000; j++)
        {
            int x = std::sin(i) + std::cos(j);
        }
    }
}

void loopsmall()
{
    for (int i = 0; i < 10; i++)
    {
        for_loop();
    }
}

void loopbig()
{
    for (int i = 0; i < 100; i++)
    {
        for_loop();
    }
}

int main()
{
    printf("pid=%d\n", getpid());
    loopbig();
    loopsmall();

    return 0;
}