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


当前回答

由于没有人提到Arm MAP,我想补充一下,因为我个人已经成功地使用了MAP来描述C++科学程序。

Arm MAP是并行、多线程或单线程C、C++、Fortran和F90代码的分析器。它提供了深入的分析和对源代码线的瓶颈定位。与大多数评测器不同,它被设计为能够评测pthreads、OpenMP或MPI的并行和线程代码。

MAP是商业软件。

其他回答

这是对Nazgob Gprof回答的回应。

过去几天我一直在使用Gprof,已经发现了三个重要的限制,其中一个是我在其他地方还没有看到过的:

它不能在多线程代码上正常工作,除非您使用变通方法调用图被函数指针弄糊涂了。示例:我有一个名为multithread()的函数,它使我能够在指定的数组上对指定的函数进行多线程处理(两者都作为参数传递)。然而,Gprof将所有对多线程()的调用视为等效的,以计算在孩子身上花费的时间。由于我传递给多线程()的一些函数花费的时间比其他函数长得多,所以我的调用图基本上是无用的。(对于那些想知道线程是否是这里的问题的人来说:不,多线程()可以选择,在这种情况下,只在调用线程上按顺序运行所有内容)。这里说“……调用数数字是通过计数而不是采样得出的。它们是完全准确的……”。然而,我发现我的调用图给了我5345859132+784984078作为对我调用最多的函数的调用统计数据,其中第一个数字应该是直接调用,第二个递归调用(都来自它本身)。因为这意味着我有一个bug,所以我在代码中加入了长(64位)计数器,并再次运行相同的程序。我的计数:5345859132个直接调用和78094395406个自递归调用。这里有很多数字,所以我要指出,我测量的递归调用是780亿,而Gprof是7.84亿:相差100倍。两次运行都是单线程和未优化的代码,一次是编译的-g,另一次是-pg。

这是在64位Debian Lenny下运行的GNUGprof(Debian的GNUBinutils)2.18.0.20080103,如果这对任何人都有帮助的话。

您可以使用iprof库:

https://gitlab.com/Neurochrom/iprof

https://github.com/Neurochrom/iprof

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

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

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

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

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

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

这里有相关问题。

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

较新的内核(例如最新的Ubuntu内核)附带了新的“perf”工具(apt-get-install-linux-tools)AKA perf_events。

这些都配有经典的采样分析器(手册页)以及很棒的时间图表!

重要的是,这些工具可以是系统评测,而不仅仅是进程评测-它们可以显示线程、进程和内核之间的交互,并让您了解进程之间的调度和I/O依赖关系。