performance - Linux perf 中的运行时间和报告的周期计数

标签 performance x86-64 cpu-architecture matrix-multiplication perf

我在 4 核 Intel CPU(每个核心 1 个线程)上运行了单线程矩阵乘法,但 perf 中的数字没有意义。

 Performance counter stats for 'system wide':

    31,728,397,287      cpu-cycles                #    0.462 GHz                    
   131,661,730,104      ref-cycles                # 1916.425 M/sec                  
         68,701.58 msec cpu-clock                 #    4.000 CPUs utilized          
         68,701.90 msec task-clock                #    4.000 CPUs utilized          
    31,728,553,882      cpu/cpu-cycles/           #  461.830 M/sec                  

      17.176244725 seconds time elapsed

我已将 CPU 频率设置为最低并观察,所有核心都以 800MHz 运行。这意味着 1 个周期为 1.25ns。总 CPU 周期为 31,728,397,287,执行时间应为 39.66 秒,但运行时间为 17.1 秒。

我也不知道为什么 0.462 GHz 写在 cpu-cycles 前面。

有关处理器的更多信息:

Thread(s) per core:              1
Core(s) per socket:              4
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           94
Model name:                      Intel(R) Core(TM) i5-6600 CPU @ 3.30GHz
Stepping:                        3
CPU MHz:                         800.022
CPU max MHz:                     3900,0000
CPU min MHz:                     800,0000

对此有什么想法吗?

更新:

我使用 root 访问权限重新运行实验并指定用户代码。

# perf stat -a -e cycles:u,cycles,cpu-clock  ./mm_double_omp 1
Using 1 threads
Total execution Time in seconds: 15.4839418610
MM execution Time in seconds: 15.3758427450

 Performance counter stats for 'system wide':

    14,237,521,876      cycles:u                  #    0.230 GHz                    
    17,470,220,108      cycles                    #    0.282 GHz                    
         61,974.41 msec cpu-clock                 #    4.000 CPUs utilized          

      15.494002570 seconds time elapsed

如您所见,频率仍然不是 800MHz。但是,如果我不指定 -a,结果就有意义,因为 Cycles:u * (1/800MHz) 几乎与耗时相同。

# perf stat -e cycles:u,cycles,cpu-clock  ./mm_double_omp 1
Using 1 threads
Total execution Time in seconds: 16.5347361100
MM execution Time in seconds: 16.4267430900
 Performance counter stats for './mm_double_omp 1':

    13.135.516.694      cycles:u                  #    0,794 GHz                    
    13.201.778.987      cycles                    #    0,798 GHz                    
         16.541,22 msec cpu-clock                 #    1,000 CPUs utilized          

      16,544487905 seconds time elapsed

      16,522146000 seconds user
       0,019997000 seconds sys

最佳答案

I have run a single thread matrix multiplication

但是,您在运行时对所有 4 个核心的系统范围进行了计数。这就是 perf -a 的作用,以及为什么您在输出中获得Performance counter stats for 'system Wide':

因此,只要进程处于事件状态,内核的任务时钟“事件”就会计算所有 4 个内核的时间:

68,701.90 msec task-clock # 4.000 CPUs utilized

这是 68.7 CPU 秒,几乎正好是 4x 17.17 秒,这是有道理的。


I also don't know why 0.462 GHz is written in front of cpu-cycles.

这是代码处于事件状态期间所有 4 个核心的平均周期/时间。对于处于 sleep 状态的 CPU,时钟不会滴答作响,因此在您的代码保持 1 个核心忙碌期间,平均负载似乎为 4 * 462/800 = 2.31 未 sleep 的 CPU。

因此,您在系统平均运行另外 1.3 个线程时进行基准测试。 (包括中断唤醒的CPU时间)

我假设您的测量不仅限于用户空间(不包括在内核模式下花费的滴答声);这是另一种可能的效果。


如果您没有使用-a,如果您只计算用户空间周期而不是内核中花费的周期,仍然可能会出现低于硬件运行频率的情况。 (例如,perf stat --all-user,或者将 kernel.perf_event_paranoid 设置得足够高,以防止您分析有效应用 的内核中的硬件事件: u 到硬件事件,但不将它们打印为 cycles:u。)

如果您将 kernel.perf_event_paranoid sysctl 设置更改为 0,或以 root 身份运行 perf,则您应该准确地看到 800 MHz 的周期/任务时钟,因为这是线程运行时 CPU 的运行速度。

不在用户空间中花费大量周期表明您的代码在内核中花费了大量时间,如果您使用的是大数组,则可能会处理页面错误。

关于performance - Linux perf 中的运行时间和报告的周期计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71380089/

相关文章:

assembly - 为什么 TZCNT 适用于我的 Sandy Bridge 处理器?

performance - x86_64 : is IMUL faster than 2x SHL + 2x ADD?

cpu-architecture - 为什么指令高速缓存对齐可提高集合关联高速缓存实现中的性能?

javascript - 用于 jquery 性能优化的 Web 浏览器插件

mysql - DATETIME 类型的时间信息可以用 BIGINT 或 DOUBLE 替代(Unix 时间)

mysql - 扩展面向列的 Mysql - Wordpress

gcc - GCC 内联汇编中的 C 数组?

c - 位移超出允许范围

linux - arm "versions?"之间的差异(仅限 ARMv7)

performance - go 应用程序的 pprof CPU 配置文件不显示任何示例