C++性能优化—CPU占用分析

软件的性能分析,往往需要查看 CPU 耗时,了解瓶颈在哪里。perf和火焰图是性能分析的利器。本文主要介绍它们的基本用法。

一、perf性能分析工具

perf (performance 的缩写)是 Linux 系统原生提供的性能分析工具,会返回 CPU 正在执行的函数名以及调用栈(stack)。它的主要作用是对程序的调用栈进行采样分析,通过调用栈反推出函数的调用次数、关系和CPU消耗时间。

1、安装perf

perf包含在linux-tools库里,我们可以通过下方的指令来安装它:

sudo apt install linux-tools-common linux-tools-generic linux-tools-`uname -r`

2、录制CPU执行堆栈

通常,它的执行频率是 99Hz(每秒99次),如果99次都返回同一个函数名,那就说明 CPU 这一秒钟都在执行同一个函数,可能存在性能问题。

sudo perf record -F 99 -a -g -p `pidof ./bin/test` -o perf.data -- sleep 30

上面的代码中,perf record表示记录,-F 99表示每秒99次,-a 表示对所有的CPU核采样,-g表示记录调用栈,-p 指定要分析的进程号,-o 指定输出文件(默认为perf.data),sleep 30则是持续30秒。

运行后会在当前目录产生一个默认名为perf.data的文本文件。如果一台服务器有16个 CPU,每秒抽样99次,持续30秒,就得到 47,520 个调用栈,长达几十万甚至上百万行,文件会非常庞大。

3、统计调用栈出现百分比

为了便于阅读,perf record命令可以统计每个调用栈出现的百分比,然后从高到低排列。

sudo perf report -i perf.data -n --stdio -f

这个结果还是不易读,所以我们需要用到下方转换为火焰图的工具。

二、FlameGraph火焰图生成工具

火焰图是基于 perf 结果产生的 SVG 图片,用来展示 CPU 的调用栈。

1、安装FlameGraph

下载火焰图生成工具FlameGraph:

git clone https://github.com/brendangregg/FlameGraph.git

2、生成火焰图

# 根据perf.data生成火焰图的步骤
sudo perf script -i perf.data > perf.unfold
./FlameGraph/stackcollapse-perf.pl perf.unfold > perf.folded
./FlameGraph/flamegraph.pl perf.folded > perf.svg
# 以上步骤也可以合为下边的指令
sudo perf script -i perf.data | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > perf.svg

3、查看火焰图

把svg文件拖到浏览器里即可查看:

  • y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。
  • x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
  • 颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。

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

*注:上图演示的是一个DDS收发演示进程,抓取过程中除了收发没有做其他工作,所以可以看到DDS占用了较多的CPU时间。

*注:增加了其他处理工作的进程,可以看到消息收发依然是占用了主要的CPU时间,其他线程占用了剩下的CPU时间。

 

yan 23.3.3

 

参考:

FlameGraph

如何读懂火焰图?

Linux perf命令详解及常用参数解析

欢迎关注下方“非著名资深码农“公众号进行交流~

3 thoughts on “C++性能优化—CPU占用分析

发表评论

邮箱地址不会被公开。