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


当前回答

这是对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,如果这对任何人都有帮助的话。

其他回答

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

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

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

您可以使用iprof库:

https://gitlab.com/Neurochrom/iprof

https://github.com/Neurochrom/iprof

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

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

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

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

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

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

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

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

我认为是这样

我会使用Valgrind和Callgrind作为我的仿形工具套件的基础。重要的是,Valgrind基本上是一台虚拟机:

(维基百科)Valgrind本质上是虚拟的机器使用准时制(JIT)编译技术,包括动态重新编译。没有来自的内容原始程序始终运行直接在主机处理器上。相反,Valgrind首先翻译将程序转换为临时的、更简单的形式称为中间表示(IR)是处理器中性的,转换后,工具(见下文)可以自由使用无论它想要什么样的转变在Valgrind翻译之前IR返回到机器代码中主机处理器运行它。

Callgrind是一个基于此的剖析器。主要的好处是,您不必运行应用程序数小时就能获得可靠的结果。因为Callgrind是一个非探测型剖面仪,所以即使一秒钟的运行也足以获得可靠的结果。

另一个基于Valgrind的工具是Massif。我使用它来分析堆内存使用情况。它工作得很好。它的作用是为您提供内存使用情况的快照--详细信息What hold What percentage of memory,and WHO has put it there。这些信息在应用程序运行的不同时间点可用。

使用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工具)