c++ - linux性能: how to interpret and find hotspots

标签 c++ linux performance profiling perf

我试用了 linux' perf今天的实用程序,并且在解释其结果时遇到了麻烦。我习惯了 valgrind 的 callgrind,这当然是完全不同的基于采样的 perf 方法。

我做了什么:

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 
...

好的,这些函数可能很慢,但是我如何知道它们是从哪里调用的呢?由于所有这些热点都位于外部库中,因此我看不到优化代码的方法。

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

这可以通过 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

这可能是我在 64 位上运行的问题吗?另见:http://lists.fedoraproject.org/pipermail/devel/2010-November/144952.html (我没有使用 fedora,但似乎适用于所有 64 位系统)。

最佳答案

Linux 3.7 perf 终于可以使用 DWARF 信息来生成调用图了:

perf record --call-graph dwarf -- yourapp
perf report -g graph --no-children

整洁,但与 VTune、KCacheGrind 或类似工具相比,curses GUI 很糟糕……我建议改用 FlameGraphs,这是一个非常简洁的可视化:http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html

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

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

perf record --call-graph lbr -- yourapp

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

关于c++ - linux性能: how to interpret and find hotspots,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7031210/

相关文章:

php - Linux 的 cron 是异步的还是同步的?

linux - 在 Tomcat 服务器上运行的负载均衡 Sonatype Nexus

正则表达式:获取每一行的一个月

c# - 在 C# 中快速复制 GUI?

swift - 为什么 `String(describing: Class.self)` 比 `NSStringFromClass(Class.self)` 慢?

c++ - 使用模板容器制作模板类

c++ - 使用 CreateFile 打开 Display 时的正确路径是什么?

java - 没有使用 JNA 获取 C++ 结构

c++ - 构建 Openssl 源代码以编译 boost

html - 哪个 CSS 更快?上限大小会提高速度吗?