下面是一个代码块,perf record 标记为导致所有 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条指令都是寄存器到寄存器指令。