利用callgrind+gprof2dot+dot进行性能分析

在确保代码运行正确无误之后,我们往往都需要进行性能优化,不过受限于阿姆达尔定律,性能优化需要针对热点代码进行。热点代码可以通过分析算法复杂度获得,也可以通过运行性能分析工具获得。在此我们给大家介绍一组工具callgrind+gprof2dot+dot,可以非常方便地分析代码瓶颈。

1.Callgrind

Valgrind是一款常用的代码分析工具,在大多数情况下我们都会用它来帮我们查找内存泄露和内存读写错误,但实际上,它的功能远不止如此。利用它的callgrind工具我们还可以对代码各部分的运行时间进行分析。使用方法如下:

valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./your_command

2.gprof2dot

上述命令会生成一个callgrind.out的性能分析文件,不过该文件不容易直接读懂,我们可以利用gprof2dot.py脚本将其转换成可以可视化的dot格式,进而利用dot命令生成图片。该脚本的使用方法很简单,基本命令如下:

python gprof2dot.py -f callgrind -n 0.5 -e 0.5 -s callgrind.out >perf.dot

简单描述就是它会分析callgrind的输出文件,并将输出结果重定向到dot格式的文件中。具体的用法我们把官网上的描述翻译一下。

2.1 命令行选项

选项含义
-o FILE, --output=FILE指定输出文件,默认是标准输出(也即屏幕),还可以通过重定向来实现该选项
-n PERCENTAGE, --node-thres=PERCENTAGE运行时间占比小于PERCENTAGE的节点(函数调用)不展示(默认阈值是0.5)
-e PERCENTAGE, --edge-thres=PERCENTAGE作用和上面类似,对边进行剪枝
-f FORMAT, --format=FORMAT性能分析日志的来源,支持的来源有:axe, callgrind, hprof, json, oprofile, perf, prof, pstats, sleepy, sysprof, xperf。该脚本支持多种性能分析工具,默认是prof,我们采用的是callgrind分析工具。
–total=TOTALMETHOD采用哪种方法统计总时间:callratios 或者 callstacks(只对perf分析工具有作用),默认是callratios 。
-c THEME, --colormap=THEME颜色主题:color, pink, gray, bw,默认是color,效果也最好。
-s, --strip不显示函数参数、模版参数、常量修饰符等对展示无影响的符号,启用该选项会让生成的图片更直观易懂,一般启用。
-w, --wrap当函数名过长的时候自动换行,启用会让生成的图片更美观
–show-samples展示function samples?
-z ROOT, --root=ROOT只展示ROOT函数及其子孙调用关系,忽略其他调用,当函数调用关系复杂只分析某一部分函数的调用关系时非常有用。
-l LEAF, --leaf=LEAF只展示某个函数及其父亲调用关系,忽略其他调用。
–skew=THEME_SKEW调整节点颜色的区分度。值<1区分度更明显,否则更不明显。建议用默认值,或者<1的值。

2.2 节点格式

输出图片中的每个节点展示一个函数调用的详细信息,具体格式如下:

function name
total time % ( self time % )
total calls

其中,total time表示该函数在总运行时间中的占比,self time表示该函数除去可显示的子函数时间之后剩余的时间占比,total calls表示该函数被调用的次数(包括递归调用)。每条边展示的是子节点的时间占比和调用次数。

2.3 FAQ

  1. 如何生成一个完整的调用图?
    默认情况下,gprof2dot脚本会忽略时间占比非常小的函数,导致生成的调用图不全。如果想统计所有函数的调用关系和时间占比,我们可以将-n和-e的阈值设置为0。
  2. 节点的函数名太长,怎么让它变窄?
    默认情况下,函数名会包括作用域,参数和模版参数等,导致函数名特别长。我们可以通过-s选项去掉这些信息,也可以通过-w命令将其换行。
  3. 脚本生成的图片为空,或者所有节点都是相同的颜色,时间占比加和不一致?
    当程序执行时间很短时,脚本无法获取足够的信息来确定各函数的执行时间导致图片为空或者时间占比加和不一致。所以使用gprof2dot的前提是程序要运行比较长的时间,这样才能获取比较准确的函数调用图。
  4. 编译时应该传递什么编译选项?
    为了生成比较准确的性能分析结果,必须要传递下面两个选项:
  • -g:产生debug信息
  • -fno-omit-frame-pointer:使用frame pointer(frame pointer usage is disabled by default in some architectures like x86_64 and for some optimization levels; it is impossible to walk the call stack without it)
    如果使用的性能分析工具是gprof,我们还需要添加-pg选项。
    如果希望分析结果和release版很接近,我们还需要添加如下两个选项:
  • -O2:初步优化
  • -DNDEBUG:禁掉标准库中的debug代码(例如assert宏)
    在很多情况下,启用代码优化之后会导致很多函数被展开,使得性能分析工具不准确,我们可以添加选项避免函数内联展开:
  • -fno-inline-functions:不要将函数展开到父函数中,这样函数计时都会归到父函数中;
  • -fno-inline-functions-called-once:和上面类似
  • -fno-optimize-sibling-calls:do not optimize sibling and tail recursive calls (otherwise tail calls may be attributed to the parent function)
    在开启比较高等级优化的情况下,有些函数即使没有加inline关键字,编译器也会自动给你展开成内联函数,可以通过下面两个选项关闭自动内联:
  • -fno-default-inline:do not make member functions inline by default merely because they are defined inside the class scope
  • -fno-inline:do not pay attention to the inline keyword Note however that with these last options the timings of functions called many times will be distorted due to the function call overhead. This is particularly true for typical C++ code which expects that these optimizations to be done for decent performance.

3.dot

dot命令是graphviz的一部分,通过编写一些类似脚本的语言,可以容易地生成流程图,其输出格式包括PostScript,PDF,SVG,PNG,含注解的文本等等,在fedora系统上可以通过yum install graphviz安装。在此我们不关注dot脚本的格式及其编写,只关心将gprof2dot生成的dot文件转换成图片进行可视化。
格式:dot -T -o <infile.dot>
输入文件是<infile.dot>,生成的格式由指定,生成的文件是。针对前面生成的perf.dot文件,我们可以通过命令dot -Tpng perf.odt -o perf.png来生成png格式的图片。另外我们也可以利用管道将上述命令组合在一起:

python gprof2dot.py -f callgrind -n 0.5 -e 0.5 -s callgrind.out | dot -Tpng -o perf.png

下面是一张用上述三个命令组合生成的一个性能分析图,从该图我们可以很清晰地看出每个函数的时间占比:性能分析图

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: perf是一个流行的系统级性能分析工具,它可以帮助用户监测系统资源的使用情况,找出程序的性能瓶颈,提高程序的运行效率。perf具有以下几个特点: 第一,perf可以监控CPU、内存、硬盘I/O、网络等系统资源的使用情况,通过分析这些数据,可以找到程序的瓶颈所在。 第二,perf支持多种测量模式,包括采样模式、跟踪模式、事件计数模式等,方便用户根据自己的需要进行性能分析。 第三,perf可以和其他一些工具结合使用,如火焰图、Callgrind等,可以更加直观地展示程序的性能瓶颈,便于用户找到问题。 第四,perf对于内核开发人员也十分有用,可以帮助他们在开发过程中找到内核的性能问题,优化内核代码。 总之,perf是一款功能强大的性能分析工具,可以帮助用户在开发过程中找到程序的性能问题,提高程序的运行效率。 ### 回答2: perf是一款开源的系统级性能分析工具,它可以帮助开发者实现对Linux系统的性能分析和优化。perf可以测量和记录CPU的使用率、缓存的效率、内存的占用、磁盘I/O的读写速度等关键性能指标。 perf具有很强的功能,如事件计数器、系统调用跟踪、板载性能监视器等。使用perf分析工具来优化代码是极为有效的,而且很容易实现。perf的操作简单易学,它使用命令行用户界面,可以轻松地探测出代码中的性能削弱点。 除此之外,perf还提供了分析结果保存、数据可视化和报告生成等功能,这些功能将有助于关键的性能指标的更好的整理和分析。perf还支持监视多线程程序,可以帮助开发人员分析并发应用程序的性能瓶颈。 总的来说,perf是一款非常强大的系统级性能分析工具,它可以帮助开发人员进行更加高效、精确地性能分析。相比于其他分析工具,perf的性能表现更加稳定,且支持多种类型的分析,因此成为了许多开发人员在Linux系统上进行性能测试和优化的首选工具之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值