基于Valgrind的callgrind工具进行代码性能分析
为了分析一些数据库产品的性能,我希望找到一种办法能够测量出各个模块或者各个函数运行的时间占比,从而找到瓶颈点,进行代码优化。
于是花了一些时间研究了一下valgrind的一个小工具callgrind的用法,并借此找到了代码的瓶颈点。因此在此记录一下这个工具的使用办法。
1. 安装valgrind
先下载
wget http://valgrind.org/downloads/valgrind-3.16.1.tar.bz2
tar -xjvf valgrind-3.16.1.tar.bz2
cd valgrind-3.16.1/
./autogen.sh
./configure
make
sudo make install
安装之后通过valgrind --version能正确查到valgrind的版本即可
2. 生成out文件
为目标程序生成分析文件,被测二进制文件为test
valgrind --tool=callgrind ./test
程序结束或者终止之后,会生成一个名为callgrind.out.<pid>的文件。其中pid为被测程序的进程ID。类似以下格式
callgrind.out.30437
这一步有可能会出现这种问题
参考这里的方法https://stackoverflow.com/questions/35129135/valgrind-reporting-a-segment-overflow
应对方法就是下载valgrind的源码,按照这个回答的方法进行修改,将m8 或者m16的值改的更大,然后重新编译安装
3.生成函数占用时间分析结果
3.1.生成文本分析
为了生成一个函数之间的调用报告,可以执行:
callgrind_annotate callgrind.out.30437
这会生成一个函数列表,此列表根据函数的独占时间来排序。如果想要非独占时间的信息,可以在上命令中添加选项--inclusive=yes。
3.2 .通过kcachegrind进行可视化
下载软件
https://jaist.dl.sourceforge.net/project/qcachegrindwin/0.7.4/
解压后,通过此软件打开out文件。可以看到函数的时间占用分布
值得注意的是,左边第一列是函数的非独占时间所占总时间的百分比,非独占时间个人理解就是函数自身运行时间加上其调用子函数的时间。
第二列是函数的独占时间所占百分比,独占时间是不包括调用子函数的时间,只有自身运行所需要的时间。
右边还可以看到特定函数下面的函数调用关系,源代码是一个dfs搜索的八皇后代码,这里的put'2是一个递归调用。
3.3 使用gprof2dot生成可视化的调用图及时间分布
安装可以根据github上所给的方式安装
https://github.com/jrfonseca/gprof2dot
gprof2dot -f callgrind -n10 -s callgrind.out.31113 > valgrind.dot
然后将dot文件转化为图片文件即可
dot -Tpng valgrind.dot -o valgrind.png
生成的图片如下图
更多详细的信息请参考valgrind官方文档:
https://valgrind.org/docs/manual/cl-manual.html#cr.dump-stats
- 点赞
- 收藏
- 关注作者
评论(0)