Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ linux性能:如何解释和查找热点_C++_Linux_Performance_Profiling_Perf - Fatal编程技术网

C++ linux性能:如何解释和查找热点

C++ linux性能:如何解释和查找热点,c++,linux,performance,profiling,perf,C++,Linux,Performance,Profiling,Perf,我今天试用了linux的实用程序,在解释它的结果时遇到了麻烦。我习惯了valgrind的callgrind,这当然是一种与基于采样的性能测试方法完全不同的方法 我所做的: perf record -g -p $(pidof someapp) perf report -g -n 现在我看到这样的情况: + 16.92% kdevelop libsqlite3.so.0.8.6 [.] 0x3fe57

我今天试用了linux的实用程序,在解释它的结果时遇到了麻烦。我习惯了valgrind的callgrind,这当然是一种与基于采样的性能测试方法完全不同的方法

我所做的:

perf record -g -p $(pidof someapp)
perf report -g -n
现在我看到这样的情况:

+ 16.92% kdevelop libsqlite3.so.0.8.6 [.] 0x3fe57 ↑ + 10.61% kdevelop libQtGui.so.4.7.3 [.] 0x81e344 ▮ + 7.09% kdevelop libc-2.14.so [.] 0x85804 ▒ + 4.96% kdevelop libQtGui.so.4.7.3 [.] 0x265b69 ▒ + 3.50% kdevelop libQtCore.so.4.7.3 [.] 0x18608d ▒ + 2.68% kdevelop libc-2.14.so [.] memcpy ▒ + 1.15% kdevelop [kernel.kallsyms] [k] copy_user_generic_string ▒ + 0.90% kdevelop libQtGui.so.4.7.3 [.] QTransform::translate(double, double) ▒ + 0.88% kdevelop libc-2.14.so [.] __libc_malloc ▒ + 0.85% kdevelop libc-2.14.so [.] memcpy ...
g++ -m64 -fno-omit-frame-pointer -g main.cpp
+16.92%kdevelop libsqlite3.so.0.8.6[.]0x3fe57↑ +10.61%kdevelop libQtGui.so.4.7.3[.]0x81e344▮ +7.09%kdevelop libc-2.14.so[.]0x85804▒ +4.96%kdevelop libQtGui.so.4.7.3[.]0x265b69▒ +3.50%kdevelop libQtCore.so.4.7.3[.]0x18608d▒ +2.68%kdevelop libc-2.14.so[.]memcpy▒ +1.15%kdevelop[kernel.kallsyms][k]复制\用户\通用\字符串▒ +0.90%kdevelop libQtGui.so.4.7.3[.]QTransform::translate(double,double)▒ +0.88%kdevelop libc-2.14.so[.]\uuu libc\u malloc▒ +0.85%kdevelop libc-2.14.so[.]memcpy ... 好的,这些函数可能很慢,但是我如何找出它们是从哪里被调用的呢?由于所有这些热点都位于外部库中,所以我看不到优化代码的方法

基本上,我在寻找一种带有累计成本注释的调用图,其中我的函数比我调用的库函数具有更高的包容性采样成本

这在perf中可能吗?如果是的话-如何

注意:我发现“E”打开调用图并提供更多信息。但是调用图通常不够深入和/或随机终止,而没有给出在哪里花费了多少信息。例如:

- 10.26% kate libkatepartinterfaces.so.4.6.0 [.] Kate::TextLoader::readLine(int&... Kate::TextLoader::readLine(int&, int&) Kate::TextBuffer::load(QString const&, bool&, bool&) KateBuffer::openFile(QString const&) KateDocument::openFile() 0x7fe37a81121c -10.26%的kate libkatePartInterface.so.4.6.0[.]kate::TextLoader::readLine(int&。。。 Kate::TextLoader::readLine(int&,int&) Kate::TextBuffer::load(QString常量&,bool&,bool&) KateBuffer::openFile(QString常量&) KateDocument::openFile() 0x7fe37a81121c
这可能是我在64位上运行的一个问题吗?另请参见:(我没有使用fedora,但似乎适用于所有64位系统)。

除非您的程序只有很少的函数,而且几乎从不调用系统函数或I/O,否则对程序计数器进行采样的分析器不会告诉您太多,正如您所发现的那样。 事实上,著名的profiler gprof是专门创建的,它试图解决只进行自我时间分析的无用性(并不是说它成功了)

真正起作用的是对调用堆栈(从而找出调用来自何处)、挂钟时间(从而包括I/O时间)进行采样,并按行或指令进行报告(从而确定您应该调查的函数调用,而不仅仅是它们所处的函数)

此外,您应该查找的统计数据是堆栈上的时间百分比,而不是调用数,也不是平均包含函数时间,尤其不是“自时间”。 如果调用指令(或非调用指令)有38%的时间在堆栈上,那么如果您可以摆脱它,您会节省多少?38%! 很简单,不是吗

这种分析器的一个例子是

在这个问题上有许多不同的看法

添加:@caf让我搜索
perf
信息,因为您包含了命令行参数
-g
,所以它会收集堆栈样本。然后您可以获取报告。 然后,如果您确保在墙上的时钟时间进行采样(这样您就得到了等待时间和cpu时间),那么您几乎已经得到了您所需要的

好的,这些函数可能很慢,但是我如何找出它们从何处被调用呢?因为所有这些热点都位于外部库中,我看不到优化代码的方法

您确定您的应用程序
someapp
是使用gcc选项
-fno省略帧指针
(可能还有它的相关库)构建的吗? 大概是这样的:

+ 16.92% kdevelop libsqlite3.so.0.8.6 [.] 0x3fe57 ↑ + 10.61% kdevelop libQtGui.so.4.7.3 [.] 0x81e344 ▮ + 7.09% kdevelop libc-2.14.so [.] 0x85804 ▒ + 4.96% kdevelop libQtGui.so.4.7.3 [.] 0x265b69 ▒ + 3.50% kdevelop libQtCore.so.4.7.3 [.] 0x18608d ▒ + 2.68% kdevelop libc-2.14.so [.] memcpy ▒ + 1.15% kdevelop [kernel.kallsyms] [k] copy_user_generic_string ▒ + 0.90% kdevelop libQtGui.so.4.7.3 [.] QTransform::translate(double, double) ▒ + 0.88% kdevelop libc-2.14.so [.] __libc_malloc ▒ + 0.85% kdevelop libc-2.14.so [.] memcpy ...
g++ -m64 -fno-omit-frame-pointer -g main.cpp

在Linux 3.7中,perf最终能够使用DWARF信息生成调用图:

perf record --call-graph dwarf -- yourapp
perf report -g graph --no-children
整洁,但与VTune、KCacheGrind或类似工具相比,curses GUI非常糟糕……我建议尝试使用FlameGraphs,这是一种非常整洁的可视化工具:

注意:在报告步骤中,
-g graph
使结果输出更容易理解“相对于总”百分比,而不是“相对于父项”数字。
--没有子项
将仅显示自成本,而不是包含成本-我也发现这一功能非常宝贵

如果您有新的perf和Intel CPU,也可以试用LBR unwinder,它具有更好的性能并生成更小的结果文件:

perf record --call-graph lbr -- yourapp

这里的缺点是,与默认的DWARF展开器配置相比,调用堆栈深度更有限。

您可以使用
perf annotate
获得非常详细的源代码级报告,请参阅。它将