性能优化工具-perf

概述

perf 是一个强大的 Linux 性能分析工具,它可以用来收集和分析性能数据。

perf的命令有很多,下文将就其中常用的几条进行阐述


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
kvm Tool to trace/measure kvm guest os
list List all symbolic event types
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
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.
top System profiling tool.
version display the version of perf binary
probe Define new dynamic tracepoints
trace strace inspired tool
kmem Tool to trace/measure kernel memory properties
kwork Tool to trace/measure kernel work properties (latencies)
lock Analyze lock events
sched Tool to trace/measure scheduler properties (latencies)
timechart Tool to visualize total system behavior during a workload

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

安装

sudo apt install linux-tools-$(uname -r)

wsl ubuntu下安装

wsl ubuntu默认的安装方式会失败,除了内核编译的方式外,还可以考虑安装generic版本(不过暂不清楚是否有兼容性问题)

sudo apt-get install linux-tools-generic
sudo ln -s /usr/lib/linux-tools/6.8.0-51-generic/perf /usr/bin/perf-generic
# 6.8.0-51可能随版本变化,大体路径是这样的

原理

perf 是 Linux 内核提供的一个性能分析工具,基于内核的 Performance Counters(性能计数器)和 Tracepoints(跟踪点)来实现。

性能计数器

Performance Counters(性能计数器)简称PC

CPU 提供了硬件计数器,用于统计特定事件的发生次数,例如 CPU 周期(cycles)、指令数(instructions)、缓存未命中(cache-misses)等。

跟踪点

  • 跟踪点是内核中预定义的钩子,用于在特定事件发生时触发。
  • perf 可以利用这些跟踪点来捕获内核或用户空间的事件。

事件

perf 支持多种事件类型,以下是一些常见的事件类型:

  1. Hardware Events: 这些事件由 CPU 硬件性能计数器提供
  2. Software Events: 这些事件由内核提供
  3. Tracepoint Events: 这些事件是内核中的特定点,可以用于跟踪特定的内核行为。
  4. Hardware Cache Events: 这些事件提供更详细的缓存行为信息
  5. Raw Events: 这些事件允许用户直接访问硬件性能计数器的原始事件编码。

使用 perf list 命令可以列出所有支持的事件。例如:

perf list

以下是一些常用的事件组

事件名称 描述 类型
cyclescpu-cycles CPU 时钟周期数 硬件事件
instructions 执行的指令数 硬件事件
branches 分支指令数 硬件事件
branch-misses 分支未命中数 硬件事件
cache-references 缓存引用数 硬件事件
cache-misses 缓存未命中数 硬件事件
task-clock 任务时钟计数 软件事件
cpu-clock CPU 时钟计数 软件事件
context-switches 上下文切换数 软件事件
cpu-migrations CPU 迁移数 软件事件
page-faults 页面错误数 软件事件
L1-dcache-loads L1 数据缓存加载数 硬件缓存事件
L1-dcache-load-misses L1 数据缓存加载未命中数 硬件缓存事件
LLC-loads 最后一级缓存加载数 硬件缓存事件
LLC-load-misses 最后一级缓存加载未命中数 硬件缓存事件
dTLB-loads 数据 TLB 加载数 硬件缓存事件
dTLB-load-misses 数据 TLB 加载未命中数 硬件缓存事件
iTLB-loads 指令 TLB 加载数 硬件缓存事件
iTLB-load-misses 指令 TLB 加载未命中数 硬件缓存事件
node-loads NUMA 节点加载数 硬件缓存事件
node-load-misses NUMA 节点加载未命中数 硬件缓存事件

采样

perf 可以通过定期采样来收集调用栈信息,从而生成火焰图或热点函数分析。

可以通过-F参数指定采样频率,默认是99

一般采样频率都不会是整数,避免采样时刚好错过一些执行

当某个事件发生频率很高,且运行时间短暂,发现该事件采样点比较少,可以考虑提高采样频率

当发现采样开销比较大,可以考虑降低采样频率

用法

perf top

统计系统的cpu的执行热点

perf top

常用选项

  • -F 指定采样率
  • -e 指定事件
  • -k 显示内核符号
  • -u 显示用户空间符号
  • -d 显示汇编代码
  • -p 指定要监控的进程
  • -C 指定要监控的cpu
  • —sort 指定排序字段

perf stat

可以查看整个系统的一段时间内的统计事件

# sudo perf stat -a sleep 10
Performance counter stats for 'system wide':

23441.54 msec cpu-clock # 12.002 CPUs utilized
2100 context-switches # 89.585 /sec
15 cpu-migrations # 0.640 /sec
2173 page-faults # 92.699 /sec
336757269 cycles # 0.014 GHz
5678431 stalled-cycles-frontend # 1.69% frontend cycles idle
17521840 stalled-cycles-backend # 5.20% backend cycles idle
137790709 instructions # 0.41 insn per cycle
# 0.13 stalled cycles per insn
31414321 branches # 1.340 M/sec
2732000 branch-misses # 8.70% of all branches

1.953170540 seconds time elapsed

sleep 10表示采集10秒,当然也可以不加这个命令,手动ctrl+c决定采集的时长

如果查看特定程序的事件,可以使用如下命令

# perf stat ls
Performance counter stats for 'ls':

1.28 msec task-clock:u # 0.611 CPUs utilized
0 context-switches:u # 0.000 /sec
0 cpu-migrations:u # 0.000 /sec
101 page-faults:u # 78.912 K/sec
1132289 cycles:u # 0.885 GHz
17919 stalled-cycles-frontend:u # 1.58% frontend cycles idle
42658 stalled-cycles-backend:u # 3.77% backend cycles idle
654934 instructions:u # 0.58 insn per cycle
# 0.07 stalled cycles per insn
133143 branches:u # 104.026 M/sec
8133 branch-misses:u # 6.11% of all branches

0.002094623 seconds time elapsed

0.000136000 seconds user
0.000000000 seconds sys

也可以具体指定要分析的 event 种类

perf stat -e cycles,instructions,cache-reference,cache-misses <program>

这将统计并显示 program 执行期间的 CPU 时钟周期数、执行的指令数和缓存未命中数。

常用选项

  • -c 设置采样周期

    perf stat -c 1000 -e cycles ./your_program
  • -C 指定采样的cpu

    sudo perf stat -C 0,1 -a sleep 10 # 这将在 10 秒内收集 CPU 0 和 CPU 1 的性能数据
  • -v 输出更详细的信息

  • -r 重复运行获取平均值

    perf stat -r 5 -e cycles,instructions ./your_program
  • 使用 -o 选项可以将输出保存到文件

  • -e 选项可以指定预定义的事件组

    # perf stat -e task-clock,context-switches
    Performance counter stats for 'system wide':

    18036.31 msec task-clock # 12.000 CPUs utilized
    1917 context-switches # 106.286 /sec

    1.503064168 seconds time elapsed

perf record

记录性能数据,生成一个性能数据文件(默认是 perf.data)。

perf record 

perf record 默认使用 cycles 事件,即 CPU 时钟周期。这是最常用的性能分析事件,用于分析 CPU 使用情况。

可以指定采集其他的事件

perf record -e cycles,instructions ./your_program

常用选项

  • -e 指定事件
  • -F 采样周期
  • -g 启用调用栈记录(内核空间+用户空间),火焰图常用
  • —call-graph 设置记录模式,火焰图常用,默认是fp模式,支持以下模式
    • fp frame-point
    • dwarf DWARF’s CFI -Call Frame Information
    • lbr Hardware Last Branch Record facility
  • --overhead 展示额外开销

有关火焰图的用法间这个文档

perf生成火焰图

perf report

分析和显示 perf record 生成的性能数据文件。

perf report

perf script

将 perf record 生成的性能数据文件转换为脚本格式,便于使用火焰图工具等进一步分析。

perf script

这个命令经常被用在生成火焰图当中

perf sched

分析调度器

perf sched record #先进行采样
perf sched latency # 然后根据采样结果,输出延迟报表

显示如下

sudo perf sched latency

-------------------------------------------------------------------------------------------------------------------------------------------
Task | Runtime ms | Switches | Avg delay ms | Max delay ms | Max delay start | Max delay end |
-------------------------------------------------------------------------------------------------------------------------------------------
:211817:211817 | 0.249 ms | 1 | avg: 0.092 ms | max: 0.092 ms | max start: 131750.828191 s | max end: 131750.828283 s
:198303:198303 | 0.206 ms | 1 | avg: 0.076 ms | max: 0.076 ms | max start: 131750.828165 s | max end: 131750.828241 s
:198094:198094 | 0.014 ms | 1 | avg: 0.074 ms | max: 0.074 ms | max start: 131750.584621 s | max end: 131750.584695 s
:211838:211838 | 0.511 ms | 2 | avg: 0.044 ms | max: 0.052 ms | max start: 131751.035039 s | max end: 131751.035090 s
:198302:198302 | 0.050 ms | 1 | avg: 0.043 ms | max: 0.043 ms | max start: 131750.828382 s | max end: 131750.828425 s
:211816:211816 | 0.045 ms | 1 | avg: 0.042 ms | max: 0.042 ms | max start: 131750.828423 s | max end: 131750.828465 s
:1957:1957 | 0.112 ms | 5 | avg: 0.041 ms | max: 0.076 ms | max start: 131750.720146 s | max end: 131750.720222 s
:1958:1958 | 0.049 ms | 2 | avg: 0.037 ms | max: 0.038 ms | max start: 131750.720493 s | max end: 131750.720531 s
:174:174 | 0.041 ms | 1 | avg: 0.037 ms | max: 0.037 ms | max start: 131751.033691 s | max end: 131751.033728 s
...
-----------------------------------------------------------------------------------------------------------------
TOTAL: | 106.102 ms | 1060 |
---------------------------------------------------

从输出中可以得到任务每次调度后的运行时间,以及切换测试,平均延时等等,进程调度延迟大多在30~90微秒左右

perf mem

显示内存访问延迟

perf mem record ./your_program
perf mem report

perf bench

支持对以下几类进行性能测试

    # List of all available benchmark collections:

sched: Scheduler and IPC benchmarks
syscall: System call benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
internals: Perf-internals benchmarks
breakpoint: Breakpoint benchmarks
uprobe: uprobe benchmarks
all: All benchmarks
key 描述
sched 调度器与进程间通信基准测试
syscall 系统调用基准测试
mem 内存访问基准测试
numa NUMA 调度与内存管理基准测试
futex 快速用户空间互斥体压力测试基准测试
epoll 事件轮询压力测试基准测试
internals 性能内部机制基准测试
breakpoint 断点基准测试
uprobe 用户空间动态探针基准测试
all 运行所有基准测试

perf bench 性能测试

perf kmem

分析内核内存分配

总结

  • perf是一个Linux的性能分析工具,他利用事件和采样机制,对程序的运行情况进行剖析

参考链接

作者

deepwzh

发布于

2024-10-10

更新于

2025-03-17

许可协议

评论