perf工具使用

perf介绍

perf 是一个强大的 Linux 性能分析工具,广泛用于分析程序的性能瓶颈,帮助开发者进行调优。perf 工具能够收集并分析多种硬件和软件事件,包括 CPU 的指令执行、缓存命中与失误、上下文切换等。

  • 硬件事件驱:通过访问 CPU 的 PMU(性能监控单元)捕获硬件级事件,如 CPU 周期数、缓存命中/未命中、分支预测失败等。
  • 采样与统计机制:采样模式,周期性记录程序执行状态,生成热点函数分布(默认基于 CPU 时钟周期);统计模式,精确记录特定事件的发生次数(如指令数、缓存访问次数);

  • 内核集成优势:直接调用内核的 tracepoint 和 kprobe 机制,支持用户态与内核态的全栈追

基本语法:

perf <command> [options]
  • command:perf 工具的子命令,例如 record、stat、report 等。
  • options:提供给 command 的选项和参数。

perf record

perf record 命令用于收集性能数据,通常用来分析程序的性能瓶颈。

perf record [options] <command>
  • -p \<pid>:指定要分析的进程的 PID。
  • -F \<frequency>:指定采样的频率(每秒钟采样次数)。例如,-F 99 每秒采样 99 次。
  • -g:收集调用图信息(调用栈信息),可以用来分析函数调用的上下文。
  • -e \<event>:指定要计数的事件。例如:-e cycles 计数 CPU 周期,-e cache-misses 计数缓存未命中
  • -- sleep \<time>:执行指定命令,并在给定的时间内采样性能数据。例如,-- sleep 30 表示记录 30 秒的数据。

示例:

perf record -F 99 -p 12345 -g -- sleep 30
# 这会对进程 PID 为 12345 的程序进行 30 秒的性能采样,采样频率为99Hz(默认是1000HZ),并收集调用图信息。
# record生成的是原始数据bin,无法直接查看,默认是生成perf.data,可以使用-o指定输出文件。
# 需要使用perf script转化才可解析。

perf report

perf report 命令用于分析和展示 perf record 记录的性能数据。

perf report [options]
  • -g:显示调用图(调用堆栈)信息,帮助分析函数的调用关系,如果要绘制图像,需要加这个参数。
  • -i \<file>:指定输入文件,默认情况下会使用 perf.data 文件。

示例:

perf report -g

这会显示 perf record 记录的性能数据的调用图。

perf script

perf script 是一个 perf 工具的子命令,主要用于将 perf record 采集到的性能数据转换为可读的格式,并允许用户对其进行进一步处理。它的主要功能是解析性能数据文件并输出到标准输出或指定文件,方便进一步分析。

perf script [options]

将 perf record 生成的性能数据(默认文件名为 perf.data)转化为易于阅读的文本格式。可以与其他工具结合,进一步分析和处理数据。

perf script -i perf.data > output.txt

指定输入文件转化为输出文件。

实践应用

perf sched

perf sched 是 perf 工具中的一个子命令,用于分析与调度相关的性能数据,主要用于分析 Linux 系统中的调度器行为(即进程和线程的调度)。这个命令可以帮助开发人员深入了解进程或线程如何在 CPU 上执行,以及在多核系统上如何分配 CPU 时间。

perf sched 命令通过分析内核的调度事件(如进程切换、上下文切换、进程调度延迟等),帮助开发人员识别系统中可能的调度瓶颈或性能问题。

抓取数据

perf sched record -a -g -o sched_raw.data &

解析数据:

killall perf
#结束进程,注意是不要使用-9强行退出,需要等待退出,保证写入的文件完整。

perf sched timehist -i sched_raw.data > sched_timehist.log

perf sched latency -i sched_raw.data > sched_latency.log
# 显示进程或线程的调度延迟,帮助你理解调度延迟如何影响系统性能。

perf sched script -i sched_raw.data > sched.log

解析数据

killall perf
#结束进程,注意是不要使用-9强行退出,需要等待退出,保证写入的文件完整。

perf sched timehist -i sched_raw.data > sched_timehist.log

perf sched latency -i sched_raw.data > sched_latency.log
# 显示进程或线程的调度延迟,帮助你理解调度延迟如何影响系统性能。

perf sched script -i sched_raw.data > sched.log

perf irq

perf irq是perf 工具中的一个子命令,用于分析与中断(IRQ, Interrupt Request)相关的性能数据。中断是操作系统用来响应硬件或软件事件的机制。perf irq 可以帮助开发者分析中断的发生频率、持续时间及其对系统性能的影响。

抓取数据

抓取中断的进入和退出

perf record -e irq:irq_handler_entry,irq:irq_handler_exit -a -g -o irq_raw.data &

解析数据

killall perf

perf script -i irq_raw.data > irq.log
perf report -i irq_raw.data > irq_report.log

火焰图

通过perf script将原始数据转换的数据,可以使用工具转换为火焰图。需要注意的时,在使用perf script转换之前,perf record需要加-g参数,记录调用栈。

火焰图工具下载链接:https://github.com/brendangregg/FlameGraph

下面是转换命令:

../FlameGraph-master/stackcollapse-perf.pl < sched.log | ../FlameGraph-master/flamegraph.pl > sched.svg

其中sched.log是perf script转换的处理的数据,先使用stackcollapse-perf.pl处理数据,然后再使用flamegraph.pl绘制图像,即可使用网页打开。

y轴(竖)表示调用栈,每一层都是一个函数,调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

x轴(横)表示抽样数,若一个函数在x轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题。

点击一层会水平放大,左上角会同时显示"Reset Zoom",点击该链接,图片就会恢复原样。