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


当前回答

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

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

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

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

这里有相关问题。

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

其他回答

您可以使用iprof库:

https://gitlab.com/Neurochrom/iprof

https://github.com/Neurochrom/iprof

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

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

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

这是我用来加速代码的两种方法:

对于CPU绑定的应用程序:

在DEBUG模式下使用探查器来识别代码中有问题的部分然后切换到RELEASE模式,注释掉代码中有问题的部分(不加任何内容),直到看到性能的变化。

对于I/O绑定应用程序:

在RELEASE模式下使用探查器来识别代码中有问题的部分。


N.B.

如果你没有剖析器,就用穷人的剖析器。调试应用程序时单击暂停。大多数开发人员套件将使用注释的行号分解成程序集。从统计上看,你很可能会在一个消耗了大部分CPU周期的区域着陆。

对于CPU来说,在DEBUG模式下进行评测的原因是,如果您尝试在RELEASE模式下进行剖析,编译器将减少数学、矢量化循环和内联函数,这些函数在汇编代码时会使代码陷入无法映射的混乱。无法映射的混乱意味着您的探查器将无法清楚地识别所需的时间,因为程序集可能与正在优化的源代码不符。如果您需要RELEASE模式的性能(例如,对时间敏感),请根据需要禁用调试器功能以保持可用的性能。

对于I/O绑定,探查器仍然可以在RELEASE模式下识别I/O操作,因为I/O操作要么在外部链接到共享库(大多数情况下),要么在最坏的情况下会导致系统调用中断向量(探查器也很容易识别)。

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

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

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

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

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

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

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

这里有相关问题。

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