perf 简介与基本使用

背景

我们面临一个问题:在运行我们的图像处理程序时,CPU占用率不是太高,但是出现不定期的延迟过高的症状,这个问题急待解决,但我们还没有比较理想的解决方式。而且在ARM Linux上编程,我们需要一个有效的方法对程序以及整个系统进行分析,找到性能瓶颈,对程序或者系统进行调优,从而最大化系统性能。下图是从国外网站上找到的一个针对Linux中各个部分进行分析的一些工具,而其中perf是很适合我们的一个。

Linux performance analysis and tools.png

perf 工具介绍

Perf 是用来进行软件性能分析的工具。通过它,应用程序可以利用 PMU,tracepoint 和内核中的特殊计数器来进行性能统计。它不但可以分析指定应用程序的性能问题 (per thread),也可以用来分析内核的性能问题,当然也可以同时分析应用代码和内核,从而全面理解应用程序中的性能瓶颈。使用 perf,您可以分析程序运行期间发生的硬件事件,比如 instructions retired ,processor clock cycles 等;您也可以分析软件事件,比如 Page Fault 和进程切换。

perf编译安装: perf工具位于Linux内核源码的tools目录下。编译perf需要先编译,libz,elfutils,binutils,若需要python脚本支持,还需要编译python。

perf处理的信息

perf list 查看当前perf工具在该系统上支持的事件。

Pc perf list.png Arm perf list.png

图上内容是perf list列出来的支持的事件的一部分,左图是odroid-XU板的,右图是soc-fpga上的。不同的CPU由于硬件结构不同,可以给perf工具处理的数据也不同。perf工具根据需要对些信息进行分析,从而获得软件于系统的运行情况。

Hardware Event

是由 PMU 硬件产生的事件,比如 cache 命中,当您需要了解程序对硬件特性的使用情况时,便需要对这些事件进行采样;

Software Event

是内核软件产生的事件,比如进程切换,tick 数等 ;

Tracepoint event

是内核中的静态 tracepoint 所触发的事件。tracepoint 是散落在内核源代码中的一些 hook,一旦使能,它们便可以在特定的代码被运行到时被触发。Perf 将 tracepoint 产生的事件记录下来,生成报告,通过分析这些报告,调优人员便可以了解程序运行时期内核的种种细节,对性能症状作出更准确的诊断。

perf基本使用

perf top

对相应事件进行实时排序显示。默认显示的事件是cpu-cycles,可以用 -e 参数设置事件。

Perf top.png

perf top 可以按照事件快速定位热点程序。如需要定位CPU占用率高的程序是哪些,或者branch miss较高的程序是哪些等。

注意,如果出现内核运行的程序的符号无法解析,需要手动进行设置,使用命令:echo 0 > /proc/sys/kernel/kptr_restrict 设置完成以后 cat /proc/sys/kernel/kptr_restrict 应该返回0 并执行命令 sysctl 即可。

perf record perf report

perf record可以用来对某一程序执行过程中的事件进行记录。在记录的时候perf会读取程序的elf文件内容,把记录紧缺到函数级别。默认记录的事件是cpu-cycles。可以用来分析各函数的CPU占用情况。

如对一下代码进行分析,把代码保存为branch.c:

#include "stdio.h"
#include "stdlib.h"
void func(void)
{
	int num = 20, i, res;
	for(i = 0; i < num; i++)
		res += 1;
}
void func_call(void)
{
	int i;
	for (i = 0; i < 100000000; i++)
		func();
}
int main()
{
	func_call();
	return 0;
}

运行命令 gcc -g branch.c -o branch 生成可执行文件branch。

注意给gcc加上-g参数以后,可执行文件中带有相关的调试信息,perf就可以解析到函数名。否则perf解析到的是一堆看不懂的函数入口地址。

对该程序进行分析只需用命令: perf record ./branch

该命令会在当前目录下生成perf记录文件 perf.data,如果需要重定向文件,加入-o参数即可。

使用命令perf report 即可对perf.data进行分析,并得到相应的执行结果。如果需要指定输入数据文件,加上-i参数即可。

Perf record.png

由图可以看到cpu主要消耗在了func函数中,着重对其进行优化,可以有效提高程序性能。

call graph

在进行软件调优的时候,还需要了解函数的调用情况,由于perf可以解析elf文件,因而可以获得相应的调用图 只需要在perf record和perf report 后面加上-g参数即可,结果如下图:

Perf call graph.png

可以根据调用情况进行调优从而提高软件调优效果。

perf stat

可以对软件进行整体评估,用perf stat -d ./branch可以查看程序branch执行的情况,加入-d参数,可以获得更详细的信息,显示信息如图所示,perf针对软件branch做了以下14个事件的统计。 可以通过这个图对软件进行总体评估。

Perf stat.png

其中:

task-clock

为系统的软件事件,表示程序在执行过程中CPU的使用情况。左边的数字单位为ms,表示该段程序使用了614.327709ms的CPU时间。右边0.999表示在运行过程中的CPU利用率,CPU利用率低表示程序运行时有大量IO等待,或上下文切换等情况而被挂起。

context-switch

表示CPU出现系统调度的上下文切换,由过多的线程或者进程造成CPU大量的任务切换,会造成CPU资源浪费。

CPU-migrations

是多核处理器中的特性,当CPU负载不均衡的时候,系统会把任务量较重的处理器上的任务分一些给任务量轻的处理器,从而实现负载平衡。

page-fault

是linux内存管理的机制,当程序请求的内存页还未被建立、不在内存中、页面访问权限不匹配、或者虽然在内存中,但还未建立虚拟地址映射关系,就会产生page-fault,内核捕获异常以后,做相应的处理。

cycles

为程序消耗的处理器周期数。3.041GHz表示处理周期数与事件的比值。

instructions

表示程序执行过程一共执行了多少条指令。后面1.76 IPC(instructions per cycle)由于x86, A9处理器都是超标量处理器,数值会大于1。但由于流水线打断等原因会使IPC降低,IPC在一定程序上可以反应程序的执行效率。

branches和branch-misses

表示处理器分支以及分支预测失败的概率。A9处理器采用8-11级流水线,并带有分支预测功能,如果分支预测失败就需要对整条流水线进行清空,对系统性能具有较大的影响,因而分析程序分支预测失效的热点代码是很有必要的。

perf sched

用来查看系统任务调度情况,对系统中的sched部分的tracepoint进行统计。包含的功能有统计系统调度延迟 latency,系统调度map图等。

使用的时候首先用命令 perf sched record 记录系统调用数据,再用perf sched latency即可生成延迟统计图表如下图所示。

Perf sched latency.png

perf timechart

这是进一步的对任务调度进行图形化的分析,首先用perf timechart record记录一段时间的调度数据,再用 perf timechart 命令生成svg矢量图,用矢量图工具inkscape即可查看任务调度情况。

Perf timechart.png

其中包含任务的 running, idle, deeper idle, deepest idle, sleeping, waiting for cpu, blacked on IO 的情况。

总结

perf的功能非常强大,可以从内核级和CPU级进行分析,可以分析的数据非常多。可以根据自己的需要进行分析。如果perf提供的基本分析功能不能满足要求,还可以通过python脚本和perl脚本对数据进行分析,用于对系统进行分析具有较大意义。

目前存在的问题

编译的时候还存在以下情况。

Perf missing function.png

其中GTK2的功能我们不需要。TUI(交互)功能不需要。python功能目前还没有必要,等需要的时候再进行移植。但trace功能历来的libaudit还没能解决。这个库的资料太少,是Redhat Linux的一个组件,我下载下来无法编译通过,尝试在我的pc上编译也无法通过,提示的问题网上没有资料。提示如下:

Libaudit error.png

并且编译完成以后链接的时候有如下提示:

Perf link warning.png

由于我们内核和文件系统不是用同一个编译器编译的,这里的glibc问题不好解决,我也没法确定这里会带来多大影响,当然目前功能基本上都是没问题的。

最后是发现工具无法生成timechart图,生成以后图上没有数据(编译好的同一个perf工具复制到xu里面可以正常生成timechart图)目前怀疑与glibc有关系。

Perf error timechart.png


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值