我使用以下代码来了解缓存未命中的行为。我正在使用gcc编译代码,然后在unix中从perf命令报告缓存统计信息。 我观察到的是,报告的未命中数远远大于访问总数。无法找出相同的原因。如果其他人已经看到类似的行为并且可能会发光,那将会非常有帮助。
#define N 30000
静态字符数组[N] [N];
int main(void){
register int i,j;
for (i=0;i<N;i++)
for(j=0;j<N;j++)
array[j][i]++;
return 0;
}
gcc test1.c -O0 -o test1.out
用于运行perf工具的perf stat -e L1-dcache-loaded,L1-dcache-load-miss,L1-dcache-stores,L1-dcache-store-miss ./test1.out
答案 0 :(得分:0)
最近,我遇到the document提及&#34;如果L1 Icache中的指令提取未命中,则在将指令返回到L1 Icache之前,可以多次重试提取。每次尝试获取时,L1 Icache未命中事件可以递增,而L2高速缓存访问计数器可以仅在初始提取时递增。&#34;我不确定数据缓存是否属实。
如果在L1从L2加载之前重试L1未命中,则L1负载也是如此。对于30000乘30000的数组,您在每次迭代中访问30000字节的数据并且l1-dcache-load失败,因此l1-dcache-load-miss计数器增加。然后,在从L2或LLC加载数据之前,它会退出以查看数据是否确实未命中,并进一步增加L1-dcache-load-miss计数器。这可能是一个很好的解释,你的L1-dcache-load-miss的情况高于L1-dcache-load。
额外注意:
当您通过perf测量程序的CPU性能时,测量包含程序和perf程序本身消耗的CPU周期。因此,请务必考虑仅由您的程序使用的周期。 perf-stat可能不允许你这样做。您可以使用perf-record和perf-report来查看程序的缓存加载和缓存未命中。
例如,您可以使用以下 perf 命令记录测量结果。
perf record -e L1-dcache-loads,L1-dcache-load-misses,L1-dcache-stores,L1-dcache-store-misses ./test1.out
然后,您可以使用以下 perf 命令查看仅适用于 test1.out 程序的录制内容。
perf report --dsos=test1.out