沉淀、分享、成长,让自己和他人都能有所收获!
perf
可以在 CPU Usage
增高的节点上找到具体的引起 CPU
增高的函数,然后我们就可以有针对性地聚焦到那个函数做分析。
Perf
这个工具最早是 Linux
内核著名开发者 Ingo Molnar
开发的,它的源代码在内核源码 tools 目录下。
使用 perf
之前,我们可以先运行一下 perf list
这个命令,然后就会看到 perf
列出了大量的 event
,比如下面这个例子就列出了常用的 event
。
从这里我们可以了解到 event
都有哪些类型, perf list
列出的每个 event
后面都有一个"[]
",里面写了这个 event
属于什么类型,比如"Hardware event
"、"Software event
"等。完整的 event
类型,我们在内核代码枚举结构 perf_type_id
里可以看到。
三个主要的 event
,它们分别是
Hardware event
:由PMU产生的事件,如L1缓存命中等。Software event
:由内核产生的事件,如进程切换等。Tracepoints event
:由内核静态跟踪点所触发的事件。perf record
命令可以用来采集数据,并且把数据写入数据文件中,随后可以通过perf report
命令对数据文件进行分析。
perf record
命令有不少的选项,常用的选项如下:
e
:选择一个事件,可以是硬件事件也可以是软件事件
-a
:全系统范围的数据采集
-p
:指定一个进程的ID
来采集特定进程的数据
-o
:指定要写入采集数据的数据文件
-g
:使能函数调用图功能
-C
:只采集某个CPU
的数据
使用案例:
perf record -a -g -- sleep 60
perf report
命令用来解析perf record
产生的数据,并给出分析结果,perf report
命令常见的选项如表:
-i
:导入的数据文件名称,默认为perf.data
-g
:生成函数调用关系图--sort
:分类统计信息,如PID
、COMM
、CPU
等例子如下:
当我们接到一个性能优化任务时,最好采用自顶向下的策略。先整体看看该程序运行时各种统计事件的汇总数据,再针对某些方向深入处理细节,而不要立即深入处理琐碎的细节,这样可能会一叶障目。
有些程序运行得慢是因为计算量太大,其多数时间在使用CPU
进行计算,这类程序叫作CPU-Bound
型;而有些程序运行得慢是因为过多的I/O
,这时其CPU
利用率应该不高,这类程序叫作I/O-Bound
型。对CPU-Bound
型程序的调优和I/O-Bound
型的调优是不同的。
perf stat
命令是一个通过概括、精简的方式提供被调试程序运行的整体情况和汇总数据的工具。perf stat
命令的选项如下所示。
-a
:显示所有CPU上的统计信息
-c
:显示指定CPU上的统计信息
-e
:指定要显示的事件
-p
:指定要显示的进程的ID
上述参数的描述如下:
task-clock
:任务真正占用的处理器时间,单位为毫秒。context-switches
:上下文的切换次数。CPU-migrations
:程序在运行过程中发生的处理器迁移次数。page-faults
:缺页异常的次数。cycles
:消耗的处理器周期数。instructions
:表示执行了多少条指令。IPC平均为每个CPU时钟周期执行了多少条指令。branches
:遇到的分支指令数。branch-misses
:预测错误的分支指令数。当你有一个明确的优化目标或者对象时,可以使用 perf stat
命令。但有些时候系统性能会无端下降。此时需要一个类似于top
的命令,以列出所有值得怀疑的进程,从中快速定位问题和缩小范围。
perf top
命令类似于Linux
系统中的top
命令,可以实时分析系统的性能瓶颈。perf top
命令常见的选项如下所示:
-e
:指定要分析的性能事件-p
:仅分析目标进程-k
:指定带符号表信息的内核映像路径-K
:不显示内核或者内核模块的符号-U
:不显示属于用户态程序的符号-g
:显示函数调用关系图例如:
终端执行如下:
# perf record -a -g -- sleep 60
# perf script > out.perf
ubuntu
进行生成火焰图
# git clone --depth 1 https://github.com/brendangregg/FlameGraph.git
# FlameGraph/stackcollapse-perf.pl out.perf > out.folded
# FlameGraph/flamegraph.pl out.folded > out.sv