【问题标题】:Fastest way to access a 3 indices array访问 3 个索引数组的最快方法
【发布时间】:2013-08-26 12:16:01
【问题描述】:

我有一个包含体积数据的线性数组。数据是灰度级的,即从 0 到 255 的整数值。

int width  = 100;
int height = 100;
int depth  = 100;

int *texture3DVolume = new int[width*height*depth];
memset(texture3DVolume,0,sizeof(int)*width*height*depth);

我正在用恒定值的球形区域填充数组的某些部分:

    int radius= 5;
    int radius2=radius*radius;
    int centerx =  // some value in [5-95] 
    int centery =  // some value in [5-95] 
    int centerz =  // some value in [5-95] 

    int cxmin=centerx-radius;
    int cxmax=centerx+radius;
    int cymin=centery-radius;
    int cymax=centery+radius;
    int czmin = centerz-radius;
    int czmax = centerz+radius;

    for ( int x= cxmin; x<cxmax; x++)
    {
        int x2 = (x-centerx)*(x-centerx);
        for ( int y=cymin; y<cymax; y++)
        {
            int x2y2= x2+(y-centery)*(y-centery);
            int slice =  textureSizeX* y + x;
            for ( int z=czmin; z<czmax; z++)
            {
                int x2y2z2 = x2y2+(z-centerz)*(z-centerz);
                if ( x2y2z2  < radius2 )
                {
                    texture3DVolume[ txty*z+slice]=255;
                }
            }
        }
    }

这里的问题是我需要访问线性数组来增强缓存的局部性。我认为这种方法虽然正确并不是最快的,因为在z 的内部循环中,我需要遍历连续的值,在我的情况下不是因为txty*z jump 为每个txty 的迭代。

我应该如何修改循环以增强数据访问局部性?

【问题讨论】:

  • txtytextureSizeX 分配给什么?
  • 与您的问题不太相关,但如果您只有 0 到 255 之间的值,您可以考虑使用 char 而不是 int(或某种 int8)。
  • txty=width*heighttextureSizeX=width 这只是一个让问题更简单的命名约定。我改变了循环嵌套,使 x 循环位于最里面,速度提高了 2 倍!

标签: c++ loops optimization memory-management


【解决方案1】:

如果可能,您应该使用std::array

array<array<array<int, 100>, 100>, 100> texture3DVolume;

然后,您应该以某种方式编写循环,即最内层坐标也是最内层循环。假设您已经检查过,您的最小值和最大值在您获得的数组边界内,例如:

for (size_t z=czmin; z<czmax; ++z)
{
    for (size_t y=cymin; z<cymax; ++y)
    {
        for (size_t x=cxmin; z<cxmax; ++x)
        {
            texture3DVolume[z][y][x] = 255;
        }
    }
}

【讨论】:

  • 推论:如果您发现自己使用 FORTRAN 编写代码,记住 FORTRAN 以相反方向 (x, y, z) 对索引进行排序以最大化缓存命中率会很有用。
  • 我的问题是关于索引一个线性数组,而不是改变它的定义。
猜你喜欢
  • 2023-03-08
  • 2021-01-14
  • 1970-01-01
  • 2017-10-29
  • 2010-11-12
  • 2022-10-25
  • 2014-03-03
  • 2012-01-19
  • 1970-01-01
相关资源
最近更新 更多