我需要访问一个带有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]
什么可能是这些位置最接近内存加速我的代码的最佳方式?
我需要访问一个带有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]
什么可能是这些位置最接近内存加速我的代码的最佳方式?
由于您没有提供足够的信息,因此很难说哪种方法更好。
你可以尝试展开你的循环来连续访问内存。
例如,从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
指令第二种方式。
如果你正在水平迭代,将矩阵排列为mat [y] [x],特别是如果它是一个数组数组(矩阵的布局在你的回答中不清晰)。
如果我得到这个正确的结果,你会遍历整个阵列,尽管你只提到x = x + 1
作为更新(y
没有)。然后我会看到阵列为一维,单个计数器i
从0
变为总阵列长度。然后四个值在每个循环访问将
mat[i], mat[i-S-m-1], mat[i-S], mat[i-1]
其中S
是步幅(行或根据你的表现列)。无论内存布局如何,这都需要较少的地址计算。它也需要较少的索引检查/更新,因为只有一个计数器i
。另外,S+m+1
是不变的,所以你可以这样定义它。
您的矩阵将会变得多大(包括维度和元素的类型)?如果它足够小以适应L1缓存,<16KB,那么访问模式并不重要。 – Michael
矩阵是一个int矩阵(258x258或258x129),所以它在130和160 Kb之间。 – cheip
您的分析器是否告诉您访问矩阵是您的应用程序的瓶颈?你有尝试过并行循环吗? –