【问题标题】:why does perf record and annotate not work?为什么 perf 记录和注释不起作用?
【发布时间】:2016-02-19 04:15:12
【问题描述】:

我被难住了,我阅读了 perf 教程,并试图在“perf stat”之外进行一个简单的测试。但是 perf record 要么不起作用,要么 perf annotate 显示没有记录样本。运行性能

例如(我使用 sudo 运行,因为没有它我会得到一堆错误,我将在最后发布):

sudo perf record -e cycles,instructions,cache-misses -a -c 1 ./FooExe

[ perf record: Woken up 4 times to write data ]
[ perf record: Captured and wrote 1.794 MB perf.data (~78393 samples) ]

.

sudo perf report -D -i perf.data |grep RECORD_SAMPLE |wc -l
Failed to open /tmp/perf-23796.map, continuing without symbols
20486

.

sudo perf annotate -d ./FooExe

the perf.data file has no samples! Press any key

所以这就是我得到的。我试图从源代码为我的系统重建性能,但这似乎也没有帮助。

我使用的是 Ubuntu 14.04 内核 3.19.0-49-generic。这是在英特尔 i7 I4510U cpu 上。我确保使用符号编译我的程序,但无论我尝试分析哪个应用程序,我都会得到相同的结果。

-- 如果我在没有 sudo 的情况下运行:

WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,
check /proc/sys/kernel/kptr_restrict.

Samples in kernel functions may not be resolved if a suitable vmlinux
file is not found in the buildid cache or in the vmlinux path.

Samples in kernel modules won't be resolved at all.

If some relocation was applied (e.g. kexec) symbols may be misresolved
even with a suitable vmlinux or kallsyms file.

Cannot read kernel map
Error:
You may not have permission to collect system-wide stats.
Consider tweaking /proc/sys/kernel/perf_event_paranoid:
 -1 - Not paranoid at all
  0 - Disallow raw tracepoint access for unpriv
  1 - Disallow cpu events for unpriv
  2 - Disallow kernel profiling for unpriv

【问题讨论】:

  • 我稍后可能会发布更大的答案,但您不需要sudoperf 尝试将在内核模式下花费的 CPU 时间包含在系统调用中。如果您只是试图分析您的代码在用户空间中的作用,则警告消息是无害的。分析仍然有效。 perf report 是否因为样本数据归根用户所有且不可读而失败?尝试删除所有 root 拥有的文件,然后在不使用 sudo 的情况下重新开始。
  • 好的,谢谢。我尝试删除 sudo 拥有的数据并重复测试。当我这样做时,如果我尝试 perf annotate -d ./FooExe 然后 perf 启动会显示一个进度条并立即退出。如果我尝试不使用 -d 选项,它只会显示“perf.data 文件没有样本”

标签: linux performance x86 perf


【解决方案1】:

我刚试过你的命令。问题是您使用-a 来分析系统范围内的所有进程,因此它从未运行./FooExe。您可以使用strace -f perf ... ./FooExe 确认这一点,并注意缺少任何execve 系统调用。而且它会立即返回,即使 FooExe 应该花费几秒钟。

这是一个为忙循环 awk 命令记录样本的示例:

perf record -e cycles,instructions,cache-misses awk 'BEGIN{for(i=0;i<40000000;i++){}}'

现在perf report 有效。您不需要为report 命令指定可执行文件,因为perf.data 只有一个可执行文件的数据。


这与 the ocperf.py wrapper 的工作方式相同,但您可以使用符号名称记录更多特定于 uarch 的事件(而不是在 -e 中查找代码和数字参数):

$ ocperf.py record -e cycles,cache-misses,uops_dispatched_port.port_0 awk 'BEGIN{for(i=0;i<40000000;i++){}}'
perf record -e cycles,cache-misses,cpu/event=0xa1,umask=0x1,name=uops_dispatched_port_port_0,period=2000003/ awk 'BEGIN{for(i=0;i<40000000;i++){}}'
  (warning lines about kernel symbols)
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.352 MB perf.data (7819 samples) 
$ ocperf.py report

【讨论】:

  • 谢谢,不知道为什么,但我可以发誓我之前尝试过(没有系统范围的标志),但无论如何,它现在看起来确实像你说的那样工作。干杯
  • 好的,现在我有另一个问题 - 我得到的输出没有显示实际符号:例如 ocperf.py record --call-graph dwarf -e misalign_mem_ref.stores -c 1 ./a.out ,然后 ocperf.py report -g graph --no-children 显示 40% a.out [unknown] [k] 0xffffffff813b4578。我确保使用 -fno-omit-frame-pointer 进行编译
  • @skimon:您是否也使用-g 编译了完整的调试符号?你确定你需要-fno-omit-frame-pointer吗?没有它的堆栈展开工作(感谢.eh_frame_hdr 部分,IIRC)。如果您让它在每个样本中记录回溯,以查看来自某些父母的电话是否比其他人更昂贵,则只需要这样做。 IDK 如果它甚至这样做;我主要搞砸了隔离我正在调整的循环并查看perf stat 输出。我实际上并没有做很多记录/注释。我认为通常它只是对指令指针进行采样。
  • 我确实使用 -g 进行了编译,SO 上的其他人有一个问答,暗示 perf 无法理解 dwarf 格式调试符号,所以我尝试使用适当的录制选项(我现在忘记了,但类似 ​​-g dwarf )。无论如何,没有骰子。 SO的另一个建议是帧指针选项。标准库 fpr 示例中的符号似乎出现了,我的代码本身没有。感谢您的帮助,最坏的情况是我可能会开始一个新问题。
猜你喜欢
  • 1970-01-01
  • 2021-02-08
  • 2011-01-29
  • 2019-07-03
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 2011-07-28
  • 2014-09-03
相关资源
最近更新 更多