欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~。python
做者:赵坤|腾讯魔王工做室后台开发工程师linux
在项目开发中,常常会遇到程序启动时间过长、CPU使用率太高等问题,这个时候须要依靠性能分析工具来定位性能的消耗点。本文介绍三个经常使用的工具的入门级使用及图形化方法,供你们参考。git
本文介绍Perf、gprof和Valgrind三个性能分析工具,及其分析结果图形化的方法,旨在让你们更快的上手使用工具。出于篇幅的限制,本文不会对每种工具的使用参数及结果分析作详细的介绍,只作入门级的使用说明,更多详细的说明你们请Google一下。github
每一个工具的介绍会分红简介、使用说明、图形化方法三个部分。算法
每种工具的结果都会基于下面这段代码:windows
#include <unistd.h>using namespace std;#define NUM 500000void init(int* int_array){ for(int i=0;i<NUM;i++){ int_array[i]=i; }}void accu(int* int_array,long& sum ){ for(int i=0;i<NUM;i++){ sum+=int_array[i]; usleep(3); }}int main(){ int int_array[NUM]; init(int_array); long sum=0; accu(int_array,sum);}
这段代码在普通PC上执行了31s,最大CPU使用率为8.3%性能优化
Perf是内置于Linux内核源码树中的性能剖析(profiling)工具。其基于事件采样原理,以性能事件为基础,经常使用于性能瓶颈的查找与热点代码的定位。服务器
perf的使用能够分为两种方式:多线程
直接使用perf启动服务svg
挂接到已启动的进程
第一种方式不须要root权限,第二种方式须要root权限
基于入门级使用这一前提,直接介绍一下使用方式:
perf record -e cpu-clock -g ./run 或者 perf record -e cpu-clock -g -p 4522
使用ctrl+c中断perf进程,或者在程序执行结束后,会产生perf.data的文件,使用
perf report
会产生结果分析,如图
perf的结果能够生成火焰图。生成火焰图须要借助Flame Graph
Flame Graph项目位于GitHub:
https://github.com/brendangregg/FlameGraph
clone代码或者直接下载压缩包到服务器上。以压缩包为例,是一个命名为:FlameGraph-master.zip的文件,假设其解压后的目录为:/data
基于1.2产生的perf.data,后续步骤以下:
一、使用perf script工具对perf.data进行解析perf script -i perf.data &> perf.unfold 二、将perf.unfold中的符号进行折叠:/data/stackcollapse-perf.pl perf.unfold &> perf.folded 三、最后生成svg图:/data/flamegraph.pl perf.folded > perf.svg
生成的火焰图以下:
关于火焰图的含义及分析网上有不少文章,这里再也不赘述
gprof用于监控程序中每一个方法的执行时间和被调用次数,方便找出程序中最耗时的函数。在程序正常退出后,会生成gmon.out文件,解析这个文件,能够生成一个可视化的报告
使用gprof,须要在编译时,加入-pg选项
另外只有在程序正常退出后才会生成gmon.out,kill进程的方法是无法生成gmon.out的。对于那些线程会一直run的服务,须要修改代码,让程序在某个时间点中止。
从新编译后,正常启动程序便可;而后在程序运行结束后,会生成gmon.out文件
使用以下命令,生成报名文件(其中run是二进制的名字):
gprof -b run gmon.out >>report.txt
report.txt打开以下图所示:
gprof的结果文件须要借助gprof2dot.py和graphviz来展现
使用gprof2dot.py生成dot文件
python gprof2dot.py report.txt >report.dot
须要说明的是,这里要求服务器已经安装了python,而且要求gprof2dot.py与安装的python版本匹配。这二者是否匹配是一个须要运气、而且解决起来很无聊的事情,个人服务器上安装的python是2.6.6,第一次从网上下载的gprof2dot-2017.9.19与python版本就不匹配,执行会出错。目前使用的版本与2.6.6是兼容的,若是须要能够与我联系。
dot的打开须要graphviz工具,我是在windows下安装的graphviz,这个工具下载很简单。下载后使用gvedit.ext打开前一个步骤产生的report.dot文件便可
这个图显的有些萌萌哒,这是由于咱们的程序写的比较简单,对于通常的业务而言,这个图会比较复杂。
valgrind不是linux的原生工具,须要自行安装。valgrind自身包含了多个工具:
Memcheck:用于内存泄漏检查
Callgrind:用于性能分析,会收集程序运行时间和调用关系
以及Cachegrind、Helgrind等
这里咱们主要使用的Callgrind工具
首先须要安装valgrind:
http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2
解压安装包后,顺次执行:./configue 、make、make install 就能够了
使用valgrind来分析性能,必须使用valgrind来启动程序:
valgrind --tool=callgrind --separate-threads=yes ./run
--separate-threads是指是否按线程来分别统计,若是不加,会将全部线程的结果打到一个文件里;不然会按线程分别打印到不一样文件里。
程序执行结束后,会生成形如:callgrind.out.4263-01的文件。这个文件直接分析起来有些困难,必须借助图形化的方式来浏览
valgrind的图形化须要借助kcachegrind.exe,你们能够自行下载,下载后在windows运行便可。这是打开callgrind.out.4263-01的结果:
对于咱们的需求:定位执行时间最长、占用CPU最多的函数 来讲,这三个工具均可以达到目的。但这三者之间仍是有必定的差距:
Perf虽然能够挂接进程但须要root权限。在普通权限下,Perf和Valgrind必须使用前缀启动的方式来启动程序,这在某种程度上会影响到程序的性能。咱们在压测的过程当中发现使用Valgrind启动的时候,能够支持的在线总人数比直接运行程序要少不少。
Perf和Valgrind都不须要修改Makefile或者程序,但gprof须要从新编译文件,而且对于线程一直run的服务,还须要修改代码让其天然退出,这在必定程序上侵入了程序。但从对性能影响上来看,gprof能够最大限制的保留原程序的性能
gprof的结果是一颗倒树,这颗树展现了从根到叶子的全部结点的时间消耗;perf的是一个金字塔,与gprof有殊途同归之妙;Valgrind的结果是一条单路,指出的是某条调用路径上的时间消耗,并非一个全局的展现。
这是一个很专业的话题,目前对三者的监控原理尚未摸的太透,因此这里暂时空着。你们有兴趣能够先行研究。
问答
相关阅读
此文已由做者受权腾讯云+社区发布,转载请注明文章出处
原文连接:https://cloud.tencent.com/developer/article/1063652