如何找到在Linux上运行的C++应用程序中运行缓慢的代码区域?
当前回答
编译和链接代码并运行可执行文件时,请使用-pg标志。执行此程序时,分析数据收集在文件a.out中。有两种不同类型的分析
1-平面轮廓:通过运行命令gprog--flat profile a.out,可以获得以下数据-该功能所花费的总时间的百分比,-在包括和排除对子函数的调用的函数中花费了多少秒,-呼叫的数量,-每次通话的平均时间。
2-图形分析使用命令gprof--graph a.out获取每个函数的以下数据,其中包括-在每个部分中,一个函数都标有索引编号。-在函数上方,有一个调用该函数的函数列表。-在函数下面,有一个函数调用的函数列表。
要获取更多信息,请查看https://sourceware.org/binutils/docs-2.32/gprof/
其他回答
在工作中,我们有一个非常好的工具,它可以帮助我们监控我们想要的日程安排。这已多次有用。
它是用C++编写的,必须根据您的需要进行定制。不幸的是,我不能共享代码,只有概念。您使用一个包含时间戳和事件ID的“大”易失性缓冲区,可以在死后或停止日志系统后转储(例如,将其转储到文件中)。
您检索包含所有数据的所谓大缓冲区,一个小接口解析它并显示带有名称(up/down+value)的事件,就像示波器使用颜色(在.hpp文件中配置)所做的那样。
您可以自定义生成的事件数量,以仅关注您所需的内容。它帮助我们解决了调度问题,同时根据每秒记录的事件数量消耗了所需的CPU数量。
您需要3个文件:
toolname.hpp // interface
toolname.cpp // code
tool_events_id.hpp // Events ID
其概念是在tool_events_id.hpp中定义如下事件:
// EVENT_NAME ID BEGIN_END BG_COLOR NAME
#define SOCK_PDU_RECV_D 0x0301 //@D00301 BGEEAAAA # TX_PDU_Recv
#define SOCK_PDU_RECV_F 0x0302 //@F00301 BGEEAAAA # TX_PDU_Recv
您还可以在toolname.hpp中定义一些函数:
#define LOG_LEVEL_ERROR 0
#define LOG_LEVEL_WARN 1
// ...
void init(void);
void probe(id,payload);
// etc
代码中可以使用的任何位置:
toolname<LOG_LEVEL>::log(EVENT_NAME,VALUE);
probe函数使用几条装配线尽快检索时钟时间戳,然后在缓冲区中设置一个条目。我们还有一个原子增量来安全地找到存储日志事件的索引。当然,缓冲区是圆形的。
希望这个想法不会因为缺少示例代码而混淆。
使用调试软件如何识别代码运行缓慢的地方?
如果你在运动中遇到障碍物,那么它会降低你的速度
如不需要的重新分配的循环、缓冲区溢出、搜索、内存泄漏等操作消耗更多的执行能力,这将对代码的性能产生不利影响,在分析之前,请确保将-pg添加到编译中:
g++your_prg.cpp-pg或cc my_program.cpp-g-pg(根据编译器)
我还没有尝试过,但我听到了关于谷歌perftools的好消息。这绝对值得一试。
valgrind--tool=callgrind/(二进制文件)
它将生成一个名为gmon.out或callgrind.out.x的文件。然后可以使用kcachegrind或调试器工具来读取该文件。它会给你一个图形化的分析结果,比如哪一行花费多少。
我认为是这样
我假设你在使用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依赖关系。
还值得一提的是
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的能力类似。
推荐文章
- fork(), vfork(), exec()和clone()的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 在tmux中保持窗口名称固定
- 是否需要手动关闭ifstream?
- 如何生成一个核心转储在Linux上的分段错误?
- 在Python中如何在Linux和Windows中使用“/”(目录分隔符)?
- 为什么函数指针定义可以使用任意数量的&号或星号* ?
- 为什么我必须通过this指针访问模板基类成员?
- 什么是可重入函数?
- 什么是栈展开?
- 如何在内存中获取对象大小?
- 我如何读整个文件到性病::字符串在c++ ?
- 如何在c++中使用枚举
- 为什么512x512矩阵的转置比513x513矩阵的转置慢得多?
- 通过引用传递数组