高效的访问问题:我需要按列访问大型矩阵(超过2000x2000),我的算法需要1行传递和1列传递。行传递对于内存效率(缓存未命中)是好的,但是如何减少列传递中的缓存未命中?我需要效率。
我唯一拥有的就是:声明n局部变量(基于内存获取大小),
int a1, a2, a3, a4;
for ( int j = 0 ; j < DIM_Y ; j+=4 ) for ( int i = 0 ; i < DIM_X ; i++ )
a1 = matrix[i][j]; ... ; a4 = matrix[i][j+4];
// make the column processing on the 4 variables.
它使用C或C ++,以及数组或int或char。
欢迎任何提议和评论。
感谢。
答案 0 :(得分:1)
适用两种基本技术:
1)循环阻塞
而不是
for (j=0;j<2000;j++)
for (i=0;i<2000;i++)
process_element(i,j);
使用
for (j=0;j<2000;j+=8)
for (i=0;i<2000;i+=8)
process_block_of_8x8(i,j);
2)2行步长的非功率(例如8192字节+64) - 必要时填充
在这种情况下,row [i] .. row [i + 7]不会争用相同的缓存行
数据应该在手动计算填充的连续内存区域中。
答案 1 :(得分:0)
存储2D矩阵的有效方法是使用C
样式数组,如下所示:
| a11 a12 a13 |
| a21 a22 a23 | -> memory: [a11,a12,a13,a21,a22,a23,a31,a32,a33]
| a31 a32 a33 |
Element(i,j) = memory[N_COL*i+j]
其中i
是从0
开始的行号索引,j
列号索引也从0
开始,N_COL
的数量是{{1}}列。
希望编译器/ jit将所有值按顺序放在内存中以便快速访问。通常,您尝试欺骗编译器的次数越多(例如手动循环展开),您在性能上的伤害就越大。编写干净的代码,让编译器完成它的工作。