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


当前回答

使用Valgrind、callgrind和kcachegrind:

valgrind --tool=callgrind ./(Your binary)

生成callgrind.out.x。使用kcachegrind读取它。

使用gprof(add-pg):

cc -o myprog myprog.c utils.c -g -pg 

(对于多线程、函数指针不太好)

使用google perftools:

使用时间采样,可以发现I/O和CPU瓶颈。

英特尔VTune是最好的(出于教育目的免费)。

其他:AMD Codeanalysis(已被AMD CodeXL取代)、OProfile、“perf”工具(apt-get-install-linux工具)

其他回答

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

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

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

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

我假设你在使用GCC。标准的解决方案是使用gprof进行分析。

在分析之前,请确保将-pg添加到编译中:

cc -o myprog myprog.c utils.c -g -pg

我还没有尝试过,但我听到了关于谷歌perftools的好消息。这绝对值得一试。

这里有相关问题。

如果gprof不适合您,还有一些流行语:Valgrind、Intel VTune、Sun DTrace。

使用调试软件如何识别代码运行缓慢的地方?

如果你在运动中遇到障碍物,那么它会降低你的速度

如不需要的重新分配的循环、缓冲区溢出、搜索、内存泄漏等操作消耗更多的执行能力,这将对代码的性能产生不利影响,在分析之前,请确保将-pg添加到编译中:

g++your_prg.cpp-pg或cc my_program.cpp-g-pg(根据编译器)

我还没有尝试过,但我听到了关于谷歌perftools的好消息。这绝对值得一试。

valgrind--tool=callgrind/(二进制文件)

它将生成一个名为gmon.out或callgrind.out.x的文件。然后可以使用kcachegrind或调试器工具来读取该文件。它会给你一个图形化的分析结果,比如哪一行花费多少。

我认为是这样

您可以使用loguru这样的日志框架,因为它包括时间戳和总运行时间,可以很好地用于分析:

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

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

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

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