Lyndra's Blog

Linux Perf工具

2024-10-19
专业知识编程开发 PerformanceLinux
8分钟
1481字
温馨提示:本文最后更新于 2025-03-11 ,部分信息可能因时间推移而不再适用,欢迎反馈。

参考:深入探索 perf CPU Profiling 实现原理perfwiki系统级性能分析工具perf的介绍与使用

  perf 是由 Linux 官方提供的系统性能分析工具 。我们通常说的 perf 实际上包含两部分:

  • perf 命令,用户空间的应用程序,是内核子系统 perf_events 的前端工具。
  • perf_events ,Linux 内核中的一个子系统。

  perf_events是Linux 2.6.31版本引入的内核子系统,可以提供多种来源的事件的性能计数器,供用户空间软件 perf 使用,完成性能分析(Performance profiling)。perf 和 perf_events 最初支持硬件计数器(performance monitoring counters,PMC),后来扩展到下列的多种事件源的支持。

  perf_events 4类事件源:

  • Hardware Events::由CPU 性能计数器(performance counters)以及其内部的 Performance Monitoring Unit (PMU)获取,用来统计 Hardware event,例如 cpu-cycles、instructions executed 、cache-misses、branch mispredicted、周期数(the number of cycles)、退役指令(instructions retired), 缓存未命中(L1 cache misses L1 )等。这些 event 因每种处理器类型和型号而异。

    注:Last Branch Record(LBR)是Intel CPU中最先引入的一个功能,记录最近执行过的分支指令,可以用来分析分支指令的执行情况,在perf list中,branch相关的功能也被划分到PMU分类,认为LBR的相关数据是通过PMU来获取的。

  • Software Events: 基于内核计数器的低优先级events, 例如, context-switches,CPU migrations(处理器迁移次数), minor faults(soft page faults),major faults(hard page faults)。

  • Tracepoints::由内核的 ftrace 实现的跟踪点事件,是散落在内核源代码中的一些 hook,用来调用probe函数。开启后,它们便可以在特定的代码被运行到时被触发,这一特性可以被各种 trace/debug 工具所使用。Perf 就是该特性的用户之一。假如您想知道在应用程序运行期间,内核内存管理模块的行为,便可以利用潜伏在 slab 分配器中的 tracepoint。当内核运行到这些 tracepoint 时,便会通知 perf。仅仅适用于2.6.3以及之后的 linux 内核。除了内核中的tracepoint,还有用户态中的,USDT(User-level statically-defined tracing)。

  • Dynamic Tracing: probe函数(探针or探测函数),kprobe(kernel probe)内核态探针,用来创建和管理内核代码中的探测点。Uprobes,user-probe,用户态探针,用来对用户态应用程序进行探测点的创建和管理,关于kprobeuprobe可参考对应的内核文档。

  下图显示了 perf 命令和 perf_events 的关系,以及 perf_events 支持的事件源。下面的分类和linux perf wiki上的perf_envent分类有些许不同,主要在与tracepoint的定义,下图包含了Static Tracing以及Dynamic Tracing。

default

  图片来源:深入探索 perf CPU Profiling 实现原理

  我们可以通过命令perf list​来查看perf支持的事件类型,但perf list​不能完全显示所有支持的事件类型,需要sudo perf list​。

  同时还可以显示特定模块支持的perf事件:hw/cache/pmu都是硬件相关的;tracepoint基于内核的ftrace;sw(software)实际上是内核计数器。

  下边列出一些sudo perf list​的输出例子:

1
branch-instructions OR branches [Hardware event]
2
context-switches OR cs [Software event]
3
cpu-clock [Software event]
4
L1-dcache-load-misses [Hardware cache event]
5
L1-dcache-loads [Hardware cache event]
6
branch-instructions OR cpu/branch-instructions/ [Kernel PMU event]
7
block:block_bio_backmerge [Tracepoint event]

  下图是很有名的brendan gregg的博客中的分类,他写了很多关于性能分析的书籍和博客。default

  图片来源:www.brendangregg.com/blog/2015-02-27/linux-profiling-at-netflix…www.brendangregg.com/perf.html

原理

  CPU 和其他硬件设备通常提供用于观测性能数据的 PMC。简单来说,PMC 就是 CPU 上的可编程寄存器,可通过编程对特定硬件事件进行计数。通过 PMC 可以监控和计算 CPU 内部各种事件,比如 CPU 指令的执行效率、CPU caches 的命中率、分支预测的成功率等微结构级别的性能信息。利用这些数据分析性能,可以实现各种性能优化。

  perf 命令通过 perf_event_open(2) 系统调用访问 PMC,配置想要捕获的硬件事件。PMC 可以在两种模式下使用:

  • Counting(计数模式),只报告Hardware Event、Software Events、PMU计数等。相关命令perf stat。开销几乎为零。
  • Sampling(采样模式),当发生一定数量的事件后,会触发一个中断,以便捕获系统的状态信息。perf将事件数据缓存到一块buffer中,然后异步写入到perf.data文件中。使用perf report等工具进行离线分析。可用于采集代码路径。
  • bpf:Kernel 4.4+新增功能,可以提供更多有效filter和输出总结。

  下面详细介绍一下 Sampling 模式:

  Perf 通过系统调用 sys_perf_event_open 陷入到内核中,内核根据 perf 提供的信息在PMU(Performance Monitoring Unit)上初始化一个硬件性能计数器(PMC: Performance Monitoring Counter)。PMC随着指定硬件事件的发生而自动累加。如果不触发溢出中断,则就是counting模式,例如 perf stat模式。

  在PMC 溢出时,PMU触发一个PMI(Performance Monitoring Interrupt)中断。内核在PMI 中断的处理函数中保存PMC的计数值,触发中断时的指令地址,当前时间戳以及当前进程的PID、TID、comm 等信息。我们把这些信息统称为一个采样(sample)。内核会将收集到的sample放入用于跟用户空间通信的Ring Buffer。用户空间里的perf分析程序采用mmap机制从ring buffer中读入采样,并对其解析。

  下图从系统调用和数据结构的层面展示了用户空间如何获取PMU信息的流程。还有一张类似的图,是来自阿里的pdf中的,被其他博客转载,或者重绘后使用,其大体内容和下图是一致的。pdf地址:类似图

default

  图片来源:plantegg.github.io/2021/05/16/Perf_IPC%E4%BB%A5%E5%8F%8ACPU%E5%8…

使用

  关于 perf 的详细使用,参考:系统级性能分析工具perf的介绍与使用

  ‍

本文标题:Linux Perf工具
文章作者:Lyndra
发布时间:2024-10-19
总访问量
总访客数人次
Copyright 2025
站点地图