我正在使用内存预取来对抗内存延迟。来自 Intel 的一些(较旧的)CPU 支持性能计数器,用于计算 CPU 因等待内存 ( stalled-cycles-backend
) 而浪费的周期,例如 Intels E5-2690
。
在较新的 CPU(例如)上Gold 6230
,Gold 6226
我找不到这个计数器。是否有另一种方法来计算 CPU 在等待内存控制器加载缓存线时浪费的周期?
我正在使用内存预取来对抗内存延迟。来自 Intel 的一些(较旧的)CPU 支持性能计数器,用于计算 CPU 因等待内存 ( stalled-cycles-backend
) 而浪费的周期,例如 Intels E5-2690
。
在较新的 CPU(例如)上Gold 6230
,Gold 6226
我找不到这个计数器。是否有另一种方法来计算 CPU 在等待内存控制器加载缓存线时浪费的周期?
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
stalled-cycles-frontend
仅在 Nehalem、Westmere、Sandy Bridge 和 Ivy Bridge 上受支持。它映射到event 0x0e, umask=0x01, inv=1, cmask=1
所有这些微架构。stalled-cycles-backend
在 Nehalem、Westmere 和 Sandy Bridge 上得到支持。在前两个上,它映射到event=0xb1, umask=0x3f, inv=1, cmask=1
. 在 SnB 上,它映射到event=0xb1, umask=0x01, inv=1, cmask=1
.
从内核 v4.6-rc1 开始,如果当前处理器不支持这些事件中的任何一个,它不会显示在perf stat
. 在早期版本的内核中,它会显示<not supported>
.
Andi Kleen(英特尔)在此线程中表示event=0xb1, umask=0x01, inv=1, cmask=1
,Ivy Bridge 不(官方)支持,并且列出该事件的手册中的表格已过时。这就是stalled-cycles-backend
IvB 不支持的原因。但根据手册 V3(2019 年 5 月)的表 19-15,它仍然为 IvB 列出。它也被列在 Broadwell 及以后,但不是 Haswell。但是,性能监控事件手册确实为 Haswell 列出了它。也许它在 Haswell 上有问题?我不知道。
根据另一个线程,这两个事件似乎已从 Haswell 开始完全放弃,转而支持自上而下方法的第一级循环分解。