我需要使用C ++代码访问二维矩阵。如果矩阵是mat[n][m]
,我必须访问(在for循环中)这些位置:
mat[x][y], mat[x-1][y-m-1], mat[x-1][y], mat[x][y-1]
在下一次迭代中,我必须这样做:
x=x+1
然后,再次:
mat[x][y], mat[x-1][y-m-1], mat[x-1][y], mat[x][y-1]
最好的方法是让这些位置在内存中最接近加速我的代码?
答案 0 :(得分:1)
如果你是水平迭代,将矩阵排列为mat [y] [x],特别是如果它是一个数组数组(矩阵的布局在你的答案中不清楚)。
答案 1 :(得分:0)
由于您没有提供足够的信息,因此很难说哪种方式更好。
您可以尝试展开循环以进行连续内存访问。
例如,从mat[x][y]
读取4次,然后mat[x-1][y-m-1]
4次,然后mat[x-1][y]
4次,然后mat[x][y-1]
4次。之后,您将在一次迭代中处理加载的4组数据。
我敢打赌瓶颈不是内存访问本身。它应该是内存地址的计算。这种内存访问方法可以用SIMD加载编写,因此可以减少内存地址计算的3/4时间成本。
如果必须按顺序处理任务,则可以尝试不使用多维订阅。例如:
for( x=0; x<n; x++ )
doSomething( mat[x][y] );
可以通过以下方式完成:
for( x=y; x<n*m; x+=m )
doSomething( mat[0][x] );
第二种方式,你避免了一条lea
指令。
答案 2 :(得分:0)
如果我做对了,你会遍历整个数组,尽管你只提到x = x + 1
作为更新(y
没有)。然后我会将数组视为一维数据,其中一个计数器i
从0
变为总数组长度。然后在每个循环中访问的四个值将是
mat[i], mat[i-S-m-1], mat[i-S], mat[i-1]
其中S
是步幅(行或列取决于您的表示)。无论内存布局如何,这都需要较少的地址计算。它还需要较少的索引检查/更新,因为只有一个计数器i
。另外,S+m+1
是常量,因此您可以将其定义为。