初始化 3d 数组的快速方法 (C++)

Jon*_*tai 3 c++ performance memory-management multidimensional-array

在我的程序中,我需要创建一个大型 3d 数组(~1GB),我当前使用两个 for 循环来初始化数组:

float*** array = new float** [m_width];

for (unsigned int i = 0; i < m_width; i++)
{
    array3d[i] = new float * [m_height];
    for (unsigned int j = 0; j < m_height; j++)
    {
        array3d[i][j] = new float[m_layers];
    }
}
Run Code Online (Sandbox Code Playgroud)

该代码工作正常,但速度非常慢。所以我的问题是:是否有更快的方法来初始化/保留多维数组的内存?(几乎可以立即创建一维数组)

Rei*_*ica 7

您没有创建 3D 数组。您正在创建一个一维指针数组,每个指针都指向一个一维指针数组,每个指针都指向一个一维数组floats。这在分配效率、缓存局部性、访问效率等方面是完全不同的。

width * height * depth如果您只创建一个 size 数组,并使用索引算术来访问它,那么效率会更高。请记住,C++ 中“动态数组”的标准拼写方式是std::vector; 这对你来说特别重要,因为vector它的所有元素都被值初始化( forfloat意味着将它们初始化为.0f)。您可以轻松创建如下内容:

class Array3d
{
  size_t height, depth;
  std::vector<float> data;

public:
  Array3d(size_t width, size_t height, size_t depth) :
    height(height),
    depth(depth),
    data(width * height * depth)
  {}

  float& at(size_t x, size_t y, size_t z)
  { return data[x * height * depth + y * depth + z]; }

  float at(size_t x, size_t y, size_t z) const
  { return data[x * height * depth + y * depth + z]; }
};
Run Code Online (Sandbox Code Playgroud)

添加更多功能、安全检查等。

速度更快的原因:

  • 关于分配:这只是对(相当昂贵的)动态分配机制的一次调用,而不是width * height + height + 1问题中的调用。

  • 访问时:这需要一些整数操作和一个指针取消引用才能访问任何数据成员。分离数组机制需要 3 次连续的内存读取(计算和偏移、检索那里的指针、偏移它、检索另一个指针,...)。