如何找到在Linux上运行的C++应用程序中运行缓慢的代码区域?
当前回答
如果没有一些选项,运行valgrind--tool=callgrind的答案并不完全。我们通常不希望在Valgrind下描述10分钟的缓慢启动时间,而希望在执行某些任务时描述我们的程序。
这就是我的建议。首先运行程序:
valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no ./binary > tmp
现在,当它工作并且我们想要开始评测时,我们应该在另一个窗口中运行:
callgrind_control -i on
这将打开分析。若要关闭并停止整个任务,我们可以使用:
callgrind_control -k
现在,我们在当前目录中有一些名为callgrind.out.*的文件。要查看分析结果,请使用:
kcachegrind callgrind.out.*
我建议在下一个窗口中单击“Self”列标题,否则它会显示“main()”是最耗时的任务。“Self”显示每个函数本身花费的时间,而不是与依赖项一起花费的时间。
其他回答
您可以使用iprof库:
https://gitlab.com/Neurochrom/iprof
https://github.com/Neurochrom/iprof
它是跨平台的,允许您不实时测量应用程序的性能。您甚至可以将其与实时图表相结合。完整免责声明:我是作者。
较新的内核(例如最新的Ubuntu内核)附带了新的“perf”工具(apt-get-install-linux-tools)AKA perf_events。
这些都配有经典的采样分析器(手册页)以及很棒的时间图表!
重要的是,这些工具可以是系统评测,而不仅仅是进程评测-它们可以显示线程、进程和内核之间的交互,并让您了解进程之间的调度和I/O依赖关系。
事实上,没有多少人提到google/基准测试,这有点让人惊讶,虽然固定代码的特定区域有点麻烦,特别是如果代码库有点大的话,但是我发现这在与callgrind结合使用时非常有用
IMHO识别导致瓶颈的工件是这里的关键。不过,我会先尝试回答以下问题,然后根据这些问题选择工具
我的算法正确吗?有锁被证明是瓶颈吗?是否有一段特定的代码被证明是罪魁祸首?IO如何处理和优化?
valgrind与callgrind和kcachegrind的结合应该能对以上几点提供一个不错的估计,一旦确定某段代码存在问题,我建议做一个微基准测试——谷歌基准测试是一个很好的开始。
您可以使用loguru这样的日志框架,因为它包括时间戳和总运行时间,可以很好地用于分析:
如果没有一些选项,运行valgrind--tool=callgrind的答案并不完全。我们通常不希望在Valgrind下描述10分钟的缓慢启动时间,而希望在执行某些任务时描述我们的程序。
这就是我的建议。首先运行程序:
valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no ./binary > tmp
现在,当它工作并且我们想要开始评测时,我们应该在另一个窗口中运行:
callgrind_control -i on
这将打开分析。若要关闭并停止整个任务,我们可以使用:
callgrind_control -k
现在,我们在当前目录中有一些名为callgrind.out.*的文件。要查看分析结果,请使用:
kcachegrind callgrind.out.*
我建议在下一个窗口中单击“Self”列标题,否则它会显示“main()”是最耗时的任务。“Self”显示每个函数本身花费的时间,而不是与依赖项一起花费的时间。
推荐文章
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 在tmux中保持窗口名称固定
- 是否需要手动关闭ifstream?
- 如何生成一个核心转储在Linux上的分段错误?
- 在Python中如何在Linux和Windows中使用“/”(目录分隔符)?
- 为什么函数指针定义可以使用任意数量的&号或星号* ?
- 为什么我必须通过this指针访问模板基类成员?
- 什么是可重入函数?
- 什么是栈展开?
- 如何在内存中获取对象大小?
- 我如何读整个文件到性病::字符串在c++ ?
- 如何在c++中使用枚举
- 为什么512x512矩阵的转置比513x513矩阵的转置慢得多?
- 通过引用传递数组
- 为什么非const引用不能绑定到临时对象?