【问题标题】:Perf instruction/cycles count in userspace/kernelspace alone in Linux在 Linux 中仅用户空间/内核空间中的 Perf 指令/周期计数
【发布时间】:2021-12-02 23:44:06
【问题描述】:

我正在尝试使用 perf 分析具有用户空间和内核空间代码的应用程序。我尝试了启用各种内核配置的所有其他可能性,但我无法获得仅在用户空间/内核空间中的指令/周期数。我尝试使用 ":u" 和 ":k 对指令和周期计数的扩展,但我得到的只是答复

$ perf stat -e cycles:u,instructions:u ls

 Performance counter stats for 'ls':

   <not supported>      cycles:u

   <not supported>      instructions:u

       0.006047045 seconds time elapsed

       0.000000000 seconds user
       0.008098000 seconds sys

但是,仅针对循环/指令运行会产生如下所示的正确结果。

$ perf stat -e cycles,instructions ls

 Performance counter stats for 'ls':

          5362086      cycles
            528783      instructions              #    0.10  insn per cycle

       0.005487940 seconds time elapsed

       0.007800000 seconds user
       0.000000000 seconds sys

注意:这里 ls 只是作为一个例子来强调问题。

我正在运行 Linux 5.4 和 perf 版本 5.4.77.g1206eede9156。而且,我正在 ARM 板上运行上述命令。以下是我在 Linux 内核中启用的配置

CONFIG_PERF_EVENTS=y
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
CONFIG_KPROBES=y
CONFIG_OPTPROBES=y
CONFIG_KPROBES_ON_FTRACE=y
CONFIG_UPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_FRAME_POINTER=y
CONFIG_FTRACE=y
CONFIG_KPROBE_EVENTS=y
CONFIG_UPROBE_EVENTS=y
CONFIG_PROBE_EVENTS=y

此外,命令行上的 perf list 列出了硬件/软件事件等等

$ perf list
  branch-instructions OR branches                    [Hardware event]
  branch-misses                                      [Hardware event]
  cache-misses                                       [Hardware event]
  cache-references                                   [Hardware event]
  cpu-cycles OR cycles                               [Hardware event]
  instructions                                       [Hardware event]
  alignment-faults                                   [Software event]
  bpf-output                                         [Software event]
  context-switches OR cs                             [Software event]
  cpu-clock                                          [Software event]
  cpu-migrations OR migrations                       [Software event]
  dummy                                              [Software event]
  emulation-faults                                   [Software event]
  major-faults                                       [Software event]
  minor-faults                                       [Software event]
  page-faults OR faults                              [Software event]
  task-clock                                         [Software event]
  duration_time                                      [Tool event]
  L1-dcache-load-misses                              [Hardware cache event]
  L1-dcache-loads                                    [Hardware cache event]
  L1-dcache-prefetch-misses                          [Hardware cache event]
  L1-dcache-prefetches                               [Hardware cache event]
  L1-dcache-store-misses                             [Hardware cache event]
  L1-dcache-stores                                   [Hardware cache event]
  L1-icache-load-misses                              [Hardware cache event]
  L1-icache-loads                                    [Hardware cache event]
  L1-icache-prefetch-misses                          [Hardware cache event]
  L1-icache-prefetches                               [Hardware cache event]
  branch-load-misses                                 [Hardware cache event]
  branch-loads                                       [Hardware cache event]
  dTLB-load-misses                                   [Hardware cache event]
  dTLB-store-misses                                  [Hardware cache event]
  iTLB-load-misses                                   [Hardware cache event]

请建议如何解决此问题。我做错了什么吗?

【问题讨论】:

    标签: linux linux-kernel profiling performancecounter perf


    【解决方案1】:

    为我工作,444,022 cycles:uperf stat -e cycles:u ls。 perf 版本 5.13.g62fb9874f5da,在 Linux 5.12.15-arch1-1 上,在裸机 (x86-64 Skylake) 上,perf_event_paranoid=0.
    (使用现代性能,您还可以使用 perf stat --all-user 来暗示所有事件的 :u。)

    我猜你的 ARM CPU 的硬件性能计数器不支持使用特权级别的掩码进行编程,因此 perf 报告说没有硬件计数器能够仅计算用户空间指令。

    AFAIK,在每个中断入口点都没有钩子来启用/禁用硬件计数器;仅计算内核、仅用户或两者都计算纯粹是硬件功能。

    显然,硬件支持对于准确计数至关重要,因为在软件实现中,计数器仍会计数,直到运行保存当前计数的内核代码。 (以及恢复状态后,返回用户空间之前的内核代码。)此外,它会使每个中断和系统调用更加昂贵,而不是仅通过在任务/线程之间的每次上下文切换中保存/恢复它们来虚拟化性能计数器。因此,内核有充分的理由不支持在软件中进行松散的尝试,即使在没有硬件支持权限掩码的 CPU 上也是如此。

    【讨论】:

    • 感谢彼得的解释。是的,可能 ARM CPU 的硬件不支持用户空间和内核空间之间的计数器隔离。但是我尝试的是执行性能记录 -e 循环,指令 ,然后执行性能报告 --stdio --sort comm,dso.. 然后将性能报告中的“事件计数(大约)”乘以总和在用户空间中运行的库的百分比和内核模块的总百分比值。这是否表明使用 :u/:k 修饰符会报告什么统计数据/记录?
    • @RVR:是的,perf record 并查看样本的用户与内核故障可能是一个不错的选择,尤其是对于循环和指令等事件,其中没有热代码可以避免生成计数他们。即使对于随着工作负载细节变化更大的事件,它也可能不会以某种方式产生太大的偏差。例如我没有看到内核执行某些会导致某些事件的明显机制,但是直到返回用户空间才实际计算它,至少不比用户空间做同样的事情更多。 (也许像缓存线输入/输出?)
    • 非常感谢您的解释。此外,对 kernel.kallsyms 的调用是什么?我在运行记录命令时看到它们被列出。来自应用程序/库的任何其他系统调用将列在 kernel.kallsyms 下?
    • @RVR:IDK,自从我详细查看perf record 输出以来已经有一段时间了。如果您没有找到关于它的现有问答并且 google 显示为空,您可以提出一个新问题。
    • 好的,谢谢,我会调查的..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 2021-10-29
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多