我想测量从L1到主内存的每个内存层次级别的延迟。所以,我试图理解https://gist.github.com/jiewmeng/3787223的1-single.c程序。为什么数组的索引由[(i * 16)& lengthMod]
[(i * 16)& lengthMod]和i * 16将始终相同。例如,
i=0, [(i * 16) & lengthMod]=0, [i*16]=0
i=1, [(i * 16) & lengthMod]=16, [i*16]=16
i=2, [(i * 16) & lengthMod]=32, [i*16]=32
i=3, [(i * 16) & lengthMod]=48, [i*16]=48
i=4, [(i * 16) & lengthMod]=64, [i*16]=64
i=5, [(i * 16) & lengthMod]=80, [i*16]=80
.........................................
所以,我试图运行程序替换[(i * 16)& lengthMod]和[i * 16],但是,程序每次都崩溃了。这就是我意识到这种按位操作背后必须有一个坚实的理由。任何人都可以解释为什么数组由[(i * 16)& lengthMod]
答案 0 :(得分:0)
在for
循环中:
for (i = 0; i < steps; i++) {
arr[(i * 16) & lengthMod] *= 10;
steps
为256 MB,arr[]
有4 MB元素。因此,如果您将数组访问权限更改为arr[i * 16]
,您将很快溢出数组并输入未定义的行为区域。
在原始代码中:
lengthMod = sizes[s] - 1;
其中sizes[]
被定义为拥有2到4MB的各种幂。因此,当您执行(i * 16) & lengthMod
时,您确保数组访问永远不会等于或超过sizes[s]
,从而防止发生阵列溢出。