一、原理
perf是Linux Kernel自带的系统性能调优工具,其相比于gprof来说不需要向被测程序中加入任何代码,非常方便、干净。
perf基于CPU的PMU(performance monitor unit)部件,在特定条件下探测性能事件是否发生以及发生的次数,主要包括系统调用次数、上下文切换次数、任务迁移次数、各级cache访问次数、各级cache丢失次数、流水线停顿周期、前端总线访问次数等。perf内置于kernel中,会对关注的事件进行采样,采样的精度可以通过在事件后添加后缀“:p”或者“:pp”来定制。
二、使用
直接在shell中敲perf能看到该命令的格式和参数,具体格式如下:
perf COMMAND [-e event ...] PROGRAM
其中,COMMAND常用命令有list、top、record、report、stat等,-e参数用于标识需要关注的事件,多个事件就用多个-e连接。
1、list
#perf list
列出所有能触发perf采样点的事件,大体上分为三类hardware(硬件产生)、software(内核软件产生)、tracepoint(内核中静态tracepoint触发事件),这个事件就是上面-e参数中的event。
2、top
#perf top
用于实时显示当前系统的整体性能统计信息,类似于top命令。
该命令可以带如下几个参数:
-p:指定进程PID
-t:指定线程TID
-a:分析整个系统的性能(默认)
-d:界面刷新周期(默认是2秒)
通过该命令可以查看当前系统最耗时的进程、线程或内核函数。这里举一个简单的例子说明之:
#vi main.cpp
int main()
{
while (true);
return 0;
}
#g++ -o main -g main.cpp
#perf top
从上图中能发现罪魁祸首main,。
3、stat
#perf stat ./main
perf stat用于分析程序的整体性能,常用参数如下:
-e:指定性能事件
-p:指定待分析进程PID
-t:指定待分析线程TID
-r:N,连续分析N次
-d:全面性能分析,采用更多的性能事件
上面指令执行后,结果如下:
有了这个结果就能找到程序热点,并对此进行调优,可以先用户调用再系统调用,常用的统计信息含义如下:
task-clock:CPU利用率,该值高,说明程序的多数时间花费在CPU计算上而非IO。
context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。
cache-misses:程序运行过程中总体的cache利用情况,如果该值过高,说明程序的cache利用不好。
cpu-migrations:表示进程运行过程中发生了多少次CPU迁移,即被调度器从一个CPU移到另外一个CPU上运行。
cycles:处理器时钟,一条机器指令可能需要多个cycles。
instructions:机器指令数目。
IPC:是Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。
cache-references:cache命中的次数。
cache-misses:cache失效的次数。
4、record/report
record记录一段时间内系统/进程的性能事件,默认在当前目录下生成统计数据文件,即perf.data。
report读取生成的perf.data文件(-i参数指定路径),显示统计结果。
通过这两参数找到百分比高的热点代码优化之,优化原则是先自己代码,后系统代码。
5、tracepoint
tracepoint是散落在内核源码中的一些hook,我们可以通过-e参数来使之启用,一旦事件触发就会通知perf以便其记录事件并生成统计报告。这里以对系统调用为例说明之,perf会统计ls命令执行时系统调用次数和耗费时间等信息:
#perf stat -e syscalls:sys_enter ls
更多信息请参看,这里,这里,,还有。