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}
- 使用方法 :
- 先使用
perf record
产生事件数据,如:perf sched record -- sleep 1
- 再使用
perf sched{latency|map|replay|script|timehist}
进行数据分析,如:perf sched timehist
2.10.1 perf sched report
2.10.2 perf sched 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
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 测试代码
// 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;
}