上下文
阅读有关缓存优化的文章(与循环中的缓存行关联)
问题与这个上下文有关:由1024个整数组成的数组。
大小: cpu缓存64k,缓存行32字节,整数大小:4字节。
英特尔核心2二人
问题
根据我的cpu,8个整数适合在一个缓存线。
[0,1,2,3,4,5,6,7,8,9,10,...,1023]
^
If I want to access 4 and go downward, 3,2,1 and 0 will be loaded already. 5,6,7 are loaded uselessly.
[0,1,2,3,4,5,6,7,8,..,1023]
^
If I want to access 7 and go downward, all the next elements will be in cache already. if I want to go upward, according to my cpu I will have to load another cache line immediatly after the arr[7] read.我说得对吗?
再进一步
但是,什么告诉我,arr4不是在一个会导致缓存行加载的地址,而不是arr7?如果我的说法是正确的,我们不仅应该考虑数组内对齐,还应该考虑整个程序的内存对齐,以尽量减少缓存浪费,对吗?
发布于 2014-11-13 16:54:52
就你的主要问题而言,是的,在这两种情况下你都是正确的。
在第二种情况下,在加载arr[7]并希望继续向上的情况下,您应该注意到编译器或某些预取机制可能会考虑到这类数据的空间局部性,从而提高性能。
更进一步说,如果数组没有在内存中正确地对齐,那么读取数组中的其他地址可能会导致缓存线加载,而不是arr[7],但在这种情况下,对齐不是由您决定,而是由编译器决定。
发布于 2014-11-13 16:18:26
但是,什么告诉我,arr4不是在一个会导致缓存行加载的地址,而不是arr7?
int数组通常在4字节边框上对齐(假设int为32位,字节为8位),因此您将不知道缓存线边框在哪里。
要吸取的教训是,您不应该担心偶尔会浪费缓存行(即使用2条缓存行,即使您需要的数据小于32字节),因为在用C编写代码时,这主要是你无法控制的。
如果您有性能问题,您可以担心的是选择减少缓存丢失的算法。
典型的例子是循环:
int array[N][M]; // Assume N * M * sizeof (int) is much larger than the cache.
// Example 1
for (i=0; i<N; i++) {
for (j=0; j<M; j++) {
<do something with array[i][j]>
}
}
// Example 2
int array[N][M];
for (j=0; j<M; j++) {
for (i=0; i<N; i++) {
<do something with array[i][j]>
}
}其中一个示例将给出大约8倍的缓存失败次数,因为它以错误的顺序访问元素。
https://stackoverflow.com/questions/26912775
复制相似问题