Perf 工具统计输出:“周期”的复用和缩放

Kai*_*esh 4 linux intel linux-kernel perf intel-pmu

我试图了解“perf”输出中“cycles”事件的复用和缩放。

以下是 perf 工具的输出:

 144094.487583      task-clock (msec)         #    1.017 CPUs utilized
  539912613776      instructions              #    1.09  insn per cycle           (83.42%)
  496622866196      cycles                    #    3.447 GHz                      (83.48%)
     340952514      cache-misses              #   10.354 % of all cache refs      (83.32%)
    3292972064      cache-references          #   22.854 M/sec                    (83.26%)
 144081.898558      cpu-clock (msec)          #    1.017 CPUs utilized
       4189372      page-faults               #    0.029 M/sec
             0      major-faults              #    0.000 K/sec
       4189372      minor-faults              #    0.029 M/sec
    8614431755      L1-dcache-load-misses     #    5.52% of all L1-dcache hits    (83.28%)
  156079653667      L1-dcache-loads           # 1083.223 M/sec                    (66.77%)

 141.622640316 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)

据我了解,内核使用多路复用为每个事件提供访问硬件的机会;因此最终的输出是估计值。

“循环”事件显示(83.48%)。我想了解这个数字是如何得出的?

我在 Intel(R) Xeon(R) CPU E5-2698 v4 @ 2.20GHz 上运行“perf”。

Zul*_*lan 6

彼得·科德斯的回答是正确的。

PMU事件比较复杂,计数器的数量有限,有些事件比较特殊,有些逻辑事件可能由多个硬件事件组成,甚至事件之间可能存在冲突。

我相信 Linux 并不知道这些限制,它只是尝试激活列表中的事件 - 更准确地说是事件组。如果无法激活所有事件,它将停止,并激活多路复用。每当多路复用计时器结束时,它就会有效地轮换事件列表,现在开始激活第二个事件,然后是第三个……Linux 不知道它仍然可以激活循环事件,因为它很特殊。

:D几乎没有记录的选项可以通过在名称后添加来固定某些事件以赋予它们优先级。我的系统上的示例:

$ perf stat -e cycles -e instructions -e cache-misses -e cache-references -e  L1-dcache-load-misses -e L1-dcache-loads ...

   119.444.297.774      cycles:u                                                      (55,88%)
   130.133.371.858      instructions:u            #    1,09  insn per cycle                                              (67,81%)
        38.277.984      cache-misses:u            #    7,780 % of all cache refs      (72,92%)
       491.979.655      cache-references:u                                            (77,00%)
     3.892.617.942      L1-dcache-load-misses:u   #   15,57% of all L1-dcache hits    (82,19%)
    25.004.563.072      L1-dcache-loads:u                                             (43,85%)
Run Code Online (Sandbox Code Playgroud)

固定指令和周期:

$ perf stat -e cycles:D -e instructions:D -e cache-misses -e cache-references -e  L1-dcache-load-misses -e L1-dcache-loads ...
   120.683.697.083      cycles:Du                                                   
   132.185.743.504      instructions:Du           #    1,10  insn per cycle                                            
        27.917.126      cache-misses:u            #    4,874 % of all cache refs      (61,14%)
       572.718.930      cache-references:u                                            (71,05%)
     3.942.313.927      L1-dcache-load-misses:u   #   15,39% of all L1-dcache hits    (80,38%)
    25.613.635.647      L1-dcache-loads:u                                             (51,37%)
Run Code Online (Sandbox Code Playgroud)

这会产生与省略周期和指令相同的多路复用:

$ perf stat -e cache-misses -e cache-references -e  L1-dcache-load-misses -e L1-dcache-loads ...

    35.333.318      cache-misses:u            #    7,212 % of all cache refs      (62,44%)
   489.922.212      cache-references:u                                            (73,87%)
 3.990.504.529      L1-dcache-load-misses:u   #   15,40% of all L1-dcache hits    (84,99%)
25.918.321.845      L1-dcache-loads:u
Run Code Online (Sandbox Code Playgroud)

请注意,您还可以对事件进行分组 ( -e \{event1,event2\}) - 这意味着事件始终一起读取 - 如果组合无法一起激活,则根本不读取。

1:始终可以添加的软件事件有一个例外。内核代码的相关部分位于kernel/events/core.c中。

  • 我浏览了调度算法的源代码。在 Broadwell 上,OP 很可能启用了超线程,并且还启用了 NMI 看门狗。所以实际上需要5个通用计数器,但只有4个可用。我还在禁用 HT 的 Broadwell 处理器上对此进行了测试,并且在此配置中没有发生多路复用。这适用于支持 Broadwell 的所有内核版本。 (2认同)