如何找到在Linux上运行的C++应用程序中运行缓慢的代码区域?


当前回答

事实上,没有多少人提到google/基准测试,这有点让人惊讶,虽然固定代码的特定区域有点麻烦,特别是如果代码库有点大的话,但是我发现这在与callgrind结合使用时非常有用

IMHO识别导致瓶颈的工件是这里的关键。不过,我会先尝试回答以下问题,然后根据这些问题选择工具

我的算法正确吗?有锁被证明是瓶颈吗?是否有一段特定的代码被证明是罪魁祸首?IO如何处理和优化?

valgrind与callgrind和kcachegrind的结合应该能对以上几点提供一个不错的估计,一旦确定某段代码存在问题,我建议做一个微基准测试——谷歌基准测试是一个很好的开始。

其他回答

您可以使用iprof库:

https://gitlab.com/Neurochrom/iprof

https://github.com/Neurochrom/iprof

它是跨平台的,允许您不实时测量应用程序的性能。您甚至可以将其与实时图表相结合。完整免责声明:我是作者。

编译和链接代码并运行可执行文件时,请使用-pg标志。执行此程序时,分析数据收集在文件a.out中。有两种不同类型的分析

1-平面轮廓:通过运行命令gprog--flat profile a.out,可以获得以下数据-该功能所花费的总时间的百分比,-在包括和排除对子函数的调用的函数中花费了多少秒,-呼叫的数量,-每次通话的平均时间。

2-图形分析使用命令gprof--graph a.out获取每个函数的以下数据,其中包括-在每个部分中,一个函数都标有索引编号。-在函数上方,有一个调用该函数的函数列表。-在函数下面,有一个函数调用的函数列表。

要获取更多信息,请查看https://sourceware.org/binutils/docs-2.32/gprof/

如果没有一些选项,运行valgrind--tool=callgrind的答案并不完全。我们通常不希望在Valgrind下描述10分钟的缓慢启动时间,而希望在执行某些任务时描述我们的程序。

这就是我的建议。首先运行程序:

valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no ./binary > tmp

现在,当它工作并且我们想要开始评测时,我们应该在另一个窗口中运行:

callgrind_control -i on

这将打开分析。若要关闭并停止整个任务,我们可以使用:

callgrind_control -k

现在,我们在当前目录中有一些名为callgrind.out.*的文件。要查看分析结果,请使用:

kcachegrind callgrind.out.*

我建议在下一个窗口中单击“Self”列标题,否则它会显示“main()”是最耗时的任务。“Self”显示每个函数本身花费的时间,而不是与依赖项一起花费的时间。

对于单线程程序,您可以使用igprof,The Ignorminous Profiler:https://igprof.org/ .

这是一个采样分析器,沿着。。。长的Mike Dunlavey的回答,它将把结果包装在一个可浏览的调用堆栈树中,用每个函数(无论是累积的还是每个函数)花费的时间或内存进行注释。

还值得一提的是

HPC工具包(http://hpctoolkit.org/)-开源,适用于并行程序,并具有一个GUI,可通过该GUI以多种方式查看结果英特尔VTune(https://software.intel.com/en-us/vtune)-如果你有英特尔编译器,这很好τ(http://www.cs.uoregon.edu/research/tau/home.php)

我使用过HPCToolkit和VTune,它们在寻找帐篷中的长极点方面非常有效,并且不需要重新编译代码(除了必须在CMake中使用-g-O或RelWithDebInfo类型的内置来获得有意义的输出)。我听说TAU的能力类似。