首页 > 解决方案 > 为什么较新的英特尔 CPU 不支持停滞周期后端的性能计数器?

问题描述

我正在使用内存预取来对抗内存延迟。来自 Intel 的一些(较旧的)CPU 支持性能计数器,用于计算 CPU 因等待内存 ( stalled-cycles-backend) 而浪费的周期,例如 Intels E5-2690

在较新的 CPU(例如)上Gold 6230Gold 6226我找不到这个计数器。是否有另一种方法来计算 CPU 在等待内存控制器加载缓存线时浪费的周期?

标签: memoryintelperformancecounterperfintel-pmu

解决方案


perf 称为“stalled-cycles-backend”的事件是一个“通用”事件,在不同的处理器模型上实现不同。这些定义很难找到,但在 CentOS 7.6 内核源代码中,定义位于“arch/x86/events/intel/core.c”中。对于 Sandy Bridge (Xeon E5-26xx),定义为 Event 0xB1, Umask 0x01, INV=1, CMASK=1。在 Intel Architectures SW Developer's Manual(文档 325384-071,2019 年 10 月)的第 3 卷第 19 章中查找此事件,表 19-3 表明在 Skylake Xeon(和 Cascade Lake Xeon)上,此事件的含义相同: “计算每个线程没有从预留站 (RS) 分派微指令的周期。”

如果您想了解计数的内容,我建议不要使用这些“通用”事件。在内核源代码中寻找定义或构建测试程序以读取执行程序的实际 MSR 是一件痛苦的事。我今天测试的第一个实际上是错误的——在 Xeon E5 v4 系统上,事件“uops_executed.core_cycles_none”被编程为事件 0xb1,Umask 0x02,INV=1,但 CMASK 未设置为 1。第 18.2 节SWDM 第 3 卷的说明如果 CMASK 为零,则忽略 INV,因此这实际上计算了执行的总 Uops,而不是没有执行 Uops 的周期。(相同的事件在运行完全相同内核的 SKX 机器上正确编程。)

在运行英特尔内存延迟测试器时计算总周期、未分派 Uop 的周期以及已分派至少一个 Uop 的周期的示例:

perf stat -e r0043003c -e r01c301b1 -e r014301b1 ./mlc --idle_latency
  Intel(R) Memory Latency Checker - v3.7
  Command line parameters: --idle_latency 

  Using buffer size of 2000.000MiB
  *** Unable to modify prefetchers (try executing 'modprobe msr')
  *** So, enabling random access for latency measurements
  Each iteration took 182.4 core clocks (   87.1    ns)


 Performance counter stats for './mlc --idle_latency':

    91,815,806,587      r0043003c                                                   
    64,132,006,584      r01c301b1                                                   
    27,683,941,060      r014301b1                                                   

      14.587156882 seconds time elapsed

推荐阅读