【发布时间】:2020-11-24 19:32:49
【问题描述】:
下面是一个代码块,它记录标记为所有 L1-dcache 未命中的 10%,但该块完全是 zmm 寄存器之间的移动。这是 perf 命令字符串:
perf record -e L1-dcache-load-misses -c 10000 -a -- ./Program_to_Test.exe
代码块:
Round:
vmulpd zmm1,zmm0,zmm28
VCVTTPD2QQ zmm0{k7},zmm1
VCVTUQQ2PD zmm2{k7},zmm0
vsubpd zmm3,zmm1,zmm2
vmulpd zmm4,zmm3,zmm27
VCVTTPD2QQ zmm5{k7}{z},zmm4
VPCMPGTQ k2,zmm5,zmm26
VPCMPEQQ k3 {k7},zmm5,zmm26
KADDQ k1,k2,k3
VCVTQQ2PD zmm2{k7},zmm0
VDIVPD zmm1{k7},zmm2,zmm28 ; Divide by 100
VPXORQ zmm2{k7},zmm2,zmm2
vmovupd zmm2,zmm1
VADDPD zmm2{k1},zmm1,zmm25
对于该代码块,我使用其他 L1 度量(例如 l1d.replacement)得到了类似的结果。
我的问题是,只有 zmm 寄存器移动的块如何产生 L1 缓存未命中?我认为寄存器根本不会进入内存。实际上,最后一次内存访问是在这块代码之上的 10 条指令;其他 9 条指令都是寄存器到寄存器指令。
【问题讨论】:
-
无论硬件事件性能使用什么,它可能都不是“精确”事件。您可能想查看
mem_load_retired.l1_miss以将 L1 未命中归因于特定的加载 uops。 -
另外,你不能使用
1./100作为倒数吗?它不能完全表示为双精度,但 div 比乘法慢很多。也许我遗漏了一些东西,但vmovupd zmm2, zmm1会覆盖前面vpxorq-zeroing 的合并屏蔽结果。如果这应该将某些元素归零,您是否可以简单地使用归零或混合? -
感谢您使用倒数的评论。我注意到当我发布这个时我仍然有一个 div 指令。此外,再次检查此代码 vpxorq 指令看起来没有必要。我测试一下看看。
-
How does Linux perf calculate the cache-references and cache-misses events 显示了
perf实际用于L1-dcache-load-misses-L1D.REPLACEMENT的硬件事件!因此,这会将同一行的多次未命中计数为仅 1 次未命中,但它与指令不同步(例如,硬件预取可能会导致它)。 Can perf account for all cache misses? 是相关的。 -
我怀疑是硬件预取,因为在下一次迭代中,我们将再次从内存中读取 64 个字节。 L1 缓存未命中可能会从上面延迟。正如你所提到的,计数器不是 100% 精确的。
标签: linux performance profiling x86-64 perf