遍历多维数组

Loop through multi-dimensional arrays

本文关键字:数组 遍历      更新时间:2023-10-16

我找到了这篇关于如何快速遍历多维数组的文章。

我正在使用Method 6: Nested loops with linear array and single incrementing index.

它说Method 8: Single loop with linear array and incrementing index更快,但我也需要嵌套循环索引。当我尝试通过 if 子句计算嵌套循环索引时,我的代码变慢了(至少比嵌套循环方法更糟糕)。

你能推荐一些计算单个指数的东西吗?

 int x1=0,x2=0; 
  for (int i1 = 1; i1 <= 10000; i1++){
             for (int i = 0; i < 10000; i++){
            x1++;
            if(x1>=100){
                x1=0;
                x2++;
             }
             if (x1 > 10)
             {
                 a[i] += a[i - 10*1];
             }
             if (x2 < 95)
             {
                 a[i] += a[i + 5*100];
             }
         }
     }

对于多维数组结构a[x1][x2]。我要计算 a[x1][x2]=a[x1-10][x2]+a[x1][x2+5]哪个a[x1][x2]转换为a[x1+x2*100]

程序代码

 method 8: 462 ns
method 6 297 ns

有没有办法在速度方面改进此代码?

您使用了错误的索引,它应该是a[ROWS][COLS]的,索引i = row * COLS + col。那么你不需要内部循环中的if s,你可以这样写:

double *v = a + 1000;    // destination
double *c = a;           // source is 10 rows before, using another pointer
                         // to take advantage of proximity in cache
for( x1 = 10; x1 < 100; x1++ ) {
    for( int x2 = 0; x2 < 95; x2++) {
        *v += *c + *(v + 5);
        ++v;
        ++c;
    }
    v += 5;  // skip the last 5 columns
    c += 5;
}

这给了我一个~130的结果,使用您发布的链接中的在线编译器

查看您的代码,您可以通过自己进行计算来避免这两个循环,这肯定不如编译器可以执行的效率。我建议您保留两个循环,但拆分循环以避免其中出现的情况,以便编译器可以将其转换为 SIMD 代码。

for(int i=0; i<10; i++) {
    for(int j=0; j<95; j++) {
        a[i * 100 + j] = a[i *100 + j + 5] 
    }
}
for(int i=10; i<100; i++) {
    for(int j=0; j<95; j++) {
        a[i * 100 + j] = a[(i - 10) * 100 + j] + a[i *100 + j + 5] 
    }
}
for(int i=10; i<100; i++) {
    for(int j=95; j<100; j++) {
        a[i * 100 + j] = a[(i - 10) * 100 + j]
    }
}

您的代码将更易于阅读。

我没有在这里测试它,但对于更大的矩阵,可以提高性能以缓存局部性。查看您的代码,您可以使用平铺来执行此操作。