C语言性能分析工具的推荐?

59

大家总是说在进行优化前要对程序进行性能分析,但很少有人描述如何进行这样的分析。

您在对C语言代码进行性能分析时采用了哪些方法?


5
你使用的编译器和操作系统是什么? - Left For Archive
6个回答

45

使用gcc编译,并使用-pg进行链接(如此处所述),然后按照该URL中建议的原则继续运行程序并使用gprof。如果您使用不同的编译器等工具,则工具可能会有所不同,但仍建议查看该URL上关于如何和为什么要对代码进行性能分析的一般想法。


2
重要的是以一种既代表应用程序正常使用方式又可重复的方式在分析器下运行您的应用程序。特定的测试用例套件会有所帮助。 - caf
在使用ELDK的PowerPC嵌入式Linux上,二进制文件无法运行,提示version GLIBC_2.16 not found - 3bdalla

15

如果你使用的是Linux操作系统,我建议结合使用ValGrindCallGrind和KCacheGrind。ValGrind非常适合用于查找内存泄漏问题,而CallGrind扩展则非常适合作为性能分析器。

注意:我刚刚了解到ValGrind现在也可以在Mac OSX上使用。但是,CallGrind和KCacheGrind自2005年以来没有更新过。您可能需要考虑其他前端工具


1
2021年更新: 根据Valgrind开发笔记(https://dev59.com/FFkR5IYBdhLWcg3w6RSo#51623185),在High Sierra之后的MAC OS X上不再支持。请使用自定义构建(https://github.com/LouisBrunner/valgrind-macos)或带有Linux的虚拟机。 - dkotenko

7

很高兴你问了这个问题 :-) 如果你不介意与众不同,请查看以下答案:

让我试着简述一下:

  1. 程序是等待你,还是你在等待它?如果它不让你等待它,那么你就没有问题,所以不要管它。

  2. 如果它让你等待,那么就继续。

我建议使用采样方法,即在程序忙碌(不等待你)时获取其运行情况的间歇性X射线。至少要获取调用栈的样本,而不仅仅是程序计数器的样本。如果你只获取程序计数器的样本,当你的程序在I/O或库例程中花费大量时间时,它将毫无意义,因此不要满足于此。

如果你想获取很多样本,你需要使用分析器。如果你只需要几个样本,调试器中的暂停按钮就可以了。根据我的经验,20个样本已经足够了,5个样本通常就足够了。

为什么呢?假设你有1000个调用栈的样本。每个样本代表一个只因栈上的每一行代码请求而花费的壁钟时间的薄片。因此,如果有一行代码出现在1000个样本中的557个样本中,你可以认为它占用了557/1000的时间,加减几个样本(15)。这意味着,如果整个执行时间花费了100美元,那么单独这一行就花费了55.70美元,误差为1.50美元**,所以你应该看看是否真的需要它。

但是你需要1000个样本吗?如果这一行代码的成本约为55.7%,那么如果你只取10个样本,你会在其中看到6个样本,加减1.5个样本。因此,如果你在10个样本中看到一条语句在其中6个样本中出现,那么你知道它大约花费了100美元中的45到75美元。即使它只花费了45美元,你也想知道是否真的需要它,不是吗?

这就是为什么你不需要很多样本 - 你不需要很高的准确度。你需要的是栈样本所提供的东西 - 它们能够精确地指出最有价值的代码行以进行优化。
** 样本数量的标准偏差为 sqrt( f * (1-f) * nsamp ),其中f是包含该行的样本比例。

非常感谢您提供如此有见地的帖子!是否有办法让 lldb 进行这种需要的随机暂停? - Koz Ross
第一个链接已失效。 - S.S. Anne
@JL2210:在我看来没问题。 - Mike Dunlavey
1
@MikeDunlavey 你是一位10K用户,而我不是。OP也不是,其他可能正在浏览该网站的非用户也不是。 - S.S. Anne
1
该问题已被删除。 - S.S. Anne
显示剩余2条评论

3
为了完整起见,我想补充一下 oprofile。如果您想对内核进行基准测试,它尤其有趣。

1

Shark和Instruments(使用dtrace)是Mac上可用的性能分析器。它们非常好用。


1
我特别喜欢Shark。非常有用(而且免费!)。 - justin

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接