固定链接 Linux Perf 性能分析工具及火焰图浅析

Linux Perf 性能分析工具及火焰图浅析

Linux Perf 性能分析工具及火焰图浅析

Perf Event 子系统

Perf 是内置于 Linux 内核源码树中的性能剖析(profiling)工具。它基于事件采样的原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。可用于性能瓶颈的查找与热点代码的定位。

本文将详细介绍 Linux Perf 的工作模式、Perf Events 的分类、Perf Tool 工具集以及火焰图的相关内容。

下图展示了Perf的整体架构。

Linux Perf 共由两部分组成:

  • Perf Tools:用户态的 Perf Tools 为用户提供了一系列丰富的工具集用于收集、分析性能数据。
  • Perf Event Subsystem:Perf Event 子系统是内核众多子系统中的一员,其主要功能是和 Perf Tool 共同完成数据采集的工作。另外,Linux Hard Lockup Detector 也是通过 Perf Event 子系统来实现的。

Perf 工作模式

  1. Couting Mode
    Counting Mode 将会精确统计一段时间内 CPU 相关硬件计数器数值的变化。为了统计用户感兴趣的事件,Perf Tool 将设置性能控制相关的寄存器。这些寄存器的值将在监控周期结束后被读出。典型工具:Perf Stat。
  2. Sampling Mode
    Sampling Mode 将以定期采样方式获取性能数据。PMU 计数器将为某些特定事件配置溢出周期。当计数器溢出时,相关数据,如 IP、通用寄存器、EFLAG 将会被捕捉到。典型工具: Perf Record。

Perf Events分类

Couting 事件

Profiling 事件

Static Tracing 事件

Dynamic Tracing 事件

Perf Tool 工具集介绍

Perf Tool 是一个用户态工具集,包含了 22 种子工具集,下表具体介绍每种工具的基本功能:

名称 功能描述
annotate 根据数据文件,注解被采样到的函数,显示指令级别的热点
archive 根据数据文件中记录的build‐id,将所有被采样到的ELF文件打成压缩包。利用此压缩包,可以在任何机器上分析数据文件中记录的采样数据
bench Perf 中内置的benchmark,目前包括两套针对调度器和内存管理子系统的benchmark
buildid‐cache 管理perf 的buildid缓存。每个ELF 文件都有一个独一无二的buildid。Buildid被perf用来关联性能数据与ELF文件
buildid‐list 列出数据文件中记录的所有buildid。
diff 对比两个数据文件的差异。能够给出每个符号(函数)在热点分析上的具体差异。
evlist 列出数据文件中的所有性能事件
inject 读取perf record记录的事件流,并将其定向到标准输出中,该工具多用于分析sched switch事件
kmem 针对内存子系统的分析工具。
kvm 此工具可以用来追踪、测试运行于KVM 虚拟机上的Guest OS
list 列出当前系统支持的所有性能事件。包括硬件性能事件、软件性能事件以及检查点
lock 分析内核中的加锁信息。包括锁的争用情况,等待延迟等。
record 收集采样信息,并将其记录在数据文件中。随后可通过其它工具对数据文件进行分析
report 读取perf record 创建的数据文件,并给出热点分析结果
sched 针对调度器子系统的分析工具
script 读取perf record结果,并生成trace output
stat 剖析某个特定进程的性能概况,包括CPI、Cache 丢失率等
test Perf 对当前软硬件平台的测试工具。可以用此工具测试当前的软硬件平台(主要是处理器型号和内部版本)是否能支持perf 的所有功
timechart 生成一幅描述处理器与各进程状态变化的矢量图
top 类似于Linux 的top 命令,对系统性能进行实时分析
trace strace inspired tool.
probe 定义动态tracepoint

Perf List

Perf List:查看当前软硬件平台支持的性能事件列表,性能事件的属性。

  • u: 仅统计用户空间程序触发的性能事件
  • k: 仅统计内核触发的性能事件
  • h: 仅统计 Hypervisor 触发的性能事件
  • G: 在 KVM 虚拟机中,仅统计 Guest 系统触发的性能事件
  • H: 仅统计 Host 系统触发的性能事件
  • p: 精度级别

Perf Stat

Perf Stat:分析性能。

Perf Top

Perf Top:实时显示系统/进程的性能统计信息, 默认性能事件为 cycles ( CPU 周期数 )。与 Linux top tool 功能类似。

Perf Record

Perf Record:记录一段时间内系统/进程的性能事件, 默认性能事件为 cycles ( CPU 周期数 )。

Perf Script

读取 Perf Record 结果。

Perf Script 输出样式

火焰图

火焰图是一种剖析软件运行状态的工具,它能够快速的将频繁执行的代码路径以图式的形式展现给用户。根据 Brendan Gregg 先生的介绍,常用的火焰图包括以下 5 种:

  • CPU
  • Memory
  • Off-CPU
  • Hot/Cold
  • Differential

本文只着重介绍了 CPU 和 Off-CPU 火焰图,若读者对另三种火焰图感兴趣可参看 Brendan Gregg 先生的博客。

CPU 火焰图

CPU 火焰图反映了一段时间内用户程序在 CPU 上运行的热点,其绘制原理是对 Perf 采集到的 samples 进行解析,对函数调用栈进行归纳合并,以柱状图的形式呈现给系统管理员。

图片描述

  • 每个长方块代表了函数调用栈中的一个函数,即为一层堆栈的内容。
  • Y 轴显示堆栈的深度。顶层方块表示 CPU 上正在运行的函数。下面的函数即为它的祖先。
  • X 轴的宽度代表被采集的 sample 的数量,越宽表示采集到的越多。

绘制原理

火焰图的绘制需要 Perf Tool 以及一些 Perl 脚本的辅助。

  1. 采集样本
    通过 Perf Record 收集 CPU 热点样本原始文件。
  2. 解析样本
    通过 Perf Script 解析样本原始文件,得到样本对应的堆栈。
  3. 绘制火焰图
    统计堆栈中函数出现的频率,并以此绘制火焰图。

Off-CPU 火焰图

On CPU 火焰图可反映某时刻 CPU 的运行热点,然而它却留下了 Off-CPU 的问题:某些程序为何进入睡眠状态?睡眠时长有多久?

下图是一张 Off-CPU 时间图, 展示了一个由于系统调用而被阻塞的应用线程的运行情况。

从图中我们可以看出应用线程长时间被阻塞在 Off-CPU 状态,而这段时间则无法通过 On-CPU 火焰图反映。

Brendan Gregg 共总结了 4 种类型的 Off-CPU 火焰图:

  1. I/O 火焰图
    File I/O 或 block device I/O 的时间消耗。

  2. Off-CPU 火焰图
    分析线程睡眠路径的火焰图。
  3. Wakeup 火焰图
    分析线程被阻塞源头的火焰图。
  4. Chain 火焰图
    结合了 Off-CPU 和 Wakeup 火焰图,详细记录了线程的睡眠原因及唤醒条件。
    注意:Chain 火焰图性能开销巨大,慎用!

Off-CPU 火焰图绘制原理

通过 Off-CPU 火焰图,我们可以轻松地了解系统中任何进程的睡眠过程。其原理是利用 Perf Static Tracer 抓取一些进程调度的相关事件,并利用 Perf Inject 将这些事件合并,最终得到诱发进程睡眠的调用流程以及睡眠时间。

相关 Tracepoints 介绍

  1. sched : sched_switch
    记录了某进程引发调度器调度的执行流程,即产生进程切换的原因。产生进程切换的原因可能存在多种:

    • 时间片耗尽
    • 等待资源,如 I/O
    • 等待锁释放
    • 主动放弃 CPU
  2. sched : sched_stat_sleep
    由于主动放弃 CPU 而进入睡眠的等待事件。它记录了进程处于睡眠状态的时间。
  3. sched : sched_stat_iowait
    由于磁盘或网络 I/O 而引发的等待事件。它记录了进程因为等待 I/O 资源而进入 D 状态的时间。
  4. sched : sched_stat_blocked
    由于等待内核锁而引发的等待事件。它记录了进程等待锁释放而进入 D 状态的时间。
  5. sched : sched_stat_wait
    这个事件记录了进程在就绪队列中等待执行的时间。

实例介绍

下面这个例子介绍了如何统计系统中进入 S 状态的进程的睡眠时长及原因。

通过追踪 sched_switch 事件获取相关进程切换的调用栈;通过追踪 sched_stat_sleep 事件获取进程的睡眠时间,最后利用 Perf Inject 合并两个事件即可。下面我们看看合并的过程:

  1. 首先查看合并前的事件:

  1. 合并后的事件:

总结

本文首先介绍了 Linux Perf Event 子系统的整体架构,接着为读者展示了 Perf 的两种工作模式及各种类别的 Perf Events,之后详细介绍了 Perf Tool 的多种子工具集,最后为读者展示了 Bredan Gregg 先生引入的各种火焰图及其绘制原理。通过阅读本文,读者将会对 Linux Perf 有更为深入的理解。

引用

https://perf.wiki.kernel.org/index.php/Tutorial#Options_controlling_environment_selection
http://www.brendangregg.com/perf.html
http://www.brendangregg.com/flamegraphs.html
https://lwn.net/Articles/510120/

本文作者:禹舟健

您的留言将激励我们越做越好