在C ++中优化2D数组

时间:2010-05-01 02:34:06

标签: c++ arrays 2d optimization

我正在处理具有以下特征的2D数组:

const int cols = 500; 
const int rows = 100; 
int arr[rows][cols];

我按以下方式访问数组arr来做一些工作:

for(int k = 0; k < T; ++k) { // for each trainee
  myscore[k] = 0;
  for(int i = 0; i < cols; ++i) { // for each sample  
    for(int j = 0; j < rows; ++j) { // for each expert
      myscore[k] += delta(i, anotherArray[k][i], arr[j][i]);
    }   
  }
}

所以我担心数组'arr'而不是另一个。我需要让它更加缓存,并提高速度。我想也许可以调换阵列,但我不知道该怎么做。我的实现结果只适用于方形矩阵。我如何使其适用于非方形矩阵?

另外,将2D阵列映射到1D阵列会提升性能吗?如果是这样,我该怎么做?最后,关于我如何优化这一点的任何其他建议...我已经没有想法,但我知道arr [j] [i]是我需要进行更改的地方因为我正在访问列列而不是行,所以根本不是缓存友好。

谢谢, 赫里斯托斯

4 个答案:

答案 0 :(得分:2)

一般in-place matrix transposition 非常很难,但是如果你把它转移到另一个数组就好了,那就很简单了。

const int cols = 500; 
const int rows = 100; 

int arr[rows][cols];
// fill arr[][]

int arrT[cols][rows];
for (int r = 0; r < rows; r++) {
   for (int c = 0; c < cols; c++) {
      arrT[c][r] = arr[r][c];
   }
}

当然,根据您获得arr[][]的方式,您可以直接填写arrT[][]

但是,可能有一种更简单的简单交换循环顺序的解决方案。

for(int k = 0; k < T; ++k) { // for each trainee
  myscore[k] = 0;
  for(int j = 0; j < rows; ++j) { // for each expert
    for(int i = 0; i < cols; ++i) { // for each sample  
      myscore[k] += delta(i, anotherArray[k][i], arr[j][i]);
    }   
  }
}

答案 1 :(得分:2)

是的,1d应该比2d快。 C和C ++数组总是1d(内部)。 当你打电话给

array[row][col]

编译器实际计算

col + row * maxcols

并将其用作1d数组的实际索引。你不妨自己这样做。循环通过整个阵列会更快,随机访问将与2d阵列一样快。

答案 2 :(得分:1)

  for(int i = 0; i < N; ++i) { // for each sample  
    for(int j = 0; j < E[i]; ++j) { // for each expert
      ... arr[j][i] ... // each ++j causes a large stride => poor caching
    }   
  }

转置循环:

  for(int j = 0; j < E[i]; ++j) { // for each expert
    for(int i = 0; i < N; ++i) { // for each sample  
      ... arr[j][i] ... // each ++i looks to the next word in memory => good
    }   
  }

当然,如果没有看到程序中的其他内容,我不能说这是否会导致问题。如果delta没有副作用,你应该没事。

答案 3 :(得分:0)

您希望内存访问是相邻的。在您的情况下,只需在访问arr时交换I和j。