使用perf工具进行程序性能热点分析与优化
文章转载自:链接1 链接2
写在前面:程序的上线一般都需要对其性能进行分析优化,对一段程序进行性能优化常常会显得很盲目,第一步需要做的就是找出程序中的性能瓶颈,然后针对性能瓶颈的代码段进行优化。
在linux下找出程序的性能瓶颈长用到的工具是perf工具。perf是一个在内核里实现的采样工具,通过采样计算程序各个部分的性能占用情况。
话不多说,下面是原作者的文章:
作为程序员,在软件开发过程中,我们有的时候会遇到一些棘手的性能问题。比如下面的两种情况:
运维报告说:新上线的应用变慢了,处理器利用率也变高了。
用户对我们抱怨说:安装新应用后,跑到某个环节就卡住,系统都不响应了。
这个时候,你该怎么办呢?
在刚学编程的时候,我会去猜哪一段代码有性能问题,然后挨个给每个函数、每个循环加上计数器,通过计数器的值判断程序到底慢在哪里。但是过去的经验告诉我,这样的做法非常低效。
我花了大量的时间去做代码静态分析,调试计数器代码和反复跑慢得快宕机的代码,也不一定能猜到正确答案。而且要注意的是,这些插入到函数和循环中的计数器可能会带来非常大的性能负面影响,这些负面影响也会误导我们。
既然上述操作行不通,这里我来告诉你一个更好的办法:采样。
采样是我们遇到“处理器消耗大,程序运行慢”时,首先应该想到的办法,它最快、最高效、负面影响也相对较小。你不需要改动应用代码,仅需对正在运行的应用做一次或者两次的采样,就能迅速找到性能的热点。
不同的平台提供了不同的采样工具。Linux平台上最著名的采样工具是perf和OProfile,它们都是Linux平台上轻量化的采样工具。采样给系统和应用带来的性能开销是可控的,比向每个函数每个循环插入计数器要小的多。
perf诞生在2009年,诞生在OProfile之后。当时,OProfile已经流行起来。但是,OProfile是一个独立的工具,它的更新相对来说比较慢,跟不上Linux的发展脚步,而且开发流程也和Linux内核团队不同。所以,林纳斯(Linus)就引入了perf这样一个工具。perf的代码和Linux内核代码放在一起,是内核级的工具。
perf的开发比OProfile要活跃得多,紧紧跟着Linux内核发布的节奏,对Linux内核的支持要比OProfile好得多。而且在功能上,perf也更强大,可以对众多的软硬件事件采样,还能采集出跟踪点(trace points)的信息(比如系统调用、TCP/IP事件和文件系统操作。和我一起的很多小伙伴都转向了使用perf)。所以,我觉得perf是在Linux上做剖析分析的首选工具。
那么,今天我们就通过解决“程序CPU占用高”这一问题,来看看perf是如何帮我们解决性能问题的。
perf初体验
首先,我们看一看怎么用perf这把“牛刀”找到代码中的性能热点。
为了让你更容易理解,我用C写了一个求质数的小程序。你运行了之后,一定会偷偷问我:“你这程序怎么这么慢啊?一跑起来CPU利用率就是100%。”
别着急,我会在接下来的时间里带着你一起,用Perf找到这个小程序慢的根源。(你可以在GitHub上下载到这个程序。)https://github.com/hugulas/perftools-intro/blob/master/linux-perf/sample1/sample.c
第一步:在Linux上安装perf
第一步当然是安装perf。有些比较早期的介绍perf的文档,会建议用户通过编译perf源代码来安装,但现在绝大部分主流的Linux发行版都提供了perf的支持,不管是Redhat系列,SUSE系列还是Debian系列,安装perf