我对发生的事情cache-misses和感到困惑L1-icache-load-misses,L1-dcache-load-misses,LLC-load-misses。当我尝试perf stat所有这些方法时,答案似乎并不一致:
%$: sudo perf stat -B -e cache-references,cache-misses,cycles,instructions,branches,faults,migrations,L1-dcache-load-misses,L1-dcache-loads,L1-dcache-stores,L1-icache-load-misses,LLC-loads,LLC-load-misses,LLC-stores,LLC-store-misses,LLC-prefetches ./my_app
523,288,816 cache-references (22.89%)
205,331,370 cache-misses # 39.239 % of all cache refs (31.53%)
10,163,373,365 cycles (39.62%)
13,739,845,761 instructions # 1.35 insn per cycle (47.43%)
2,520,022,243 branches (54.90%)
20,341 faults
147 migrations
237,794,728 L1-dcache-load-misses # 6.80% of all L1-dcache hits (62.43%)
3,495,080,007 L1-dcache-loads (69.95%)
2,039,344,725 L1-dcache-stores (69.95%)
531,452,853 L1-icache-load-misses (70.11%)
77,062,627 LLC-loads (70.47%)
27,462,249 LLC-load-misses # 35.64% of all LL-cache hits (69.09%)
15,039,473 LLC-stores (15.15%) …Run Code Online (Sandbox Code Playgroud) 下面是一个代码块,perf record 标记为造成所有 L1-dcache 未命中的 10%,但该块完全是 zmm 寄存器之间的移动。这是 perf 命令字符串:
perf record -e L1-dcache-load-misses -c 10000 -a -- ./Program_to_Test.exe
Run Code Online (Sandbox Code Playgroud)
代码块:
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
Run Code Online (Sandbox Code Playgroud)
对于该代码块,我使用其他 L1 度量(例如 l1d.replacement)得到了类似的结果。
我的问题是,一个仅是 zmm 寄存器移动的块如何会产生 L1 缓存未命中?我认为寄存器根本不会进入内存。事实上,最后一次内存访问是在该代码块之上的10条指令;其他9条指令都是寄存器到寄存器指令。