【问题标题】:Fast way of initallizing a 3d array (C++)初始化 3d 数组的快速方法 (C++)
【发布时间】:2018-04-05 09:01:22
【问题描述】:

在我的程序中,我需要创建一个大型 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];
    }
}

代码运行良好,但速度很慢。 所以我的问题是:有没有更快的方法来为多维数组初始化/保留内存? (几乎可以立即创建一维数组)

【问题讨论】:

  • 你能量化一下“非常慢”吗?
  • 保留一个平面数组 (1d) 并计算在其索引处访问特定元素的维度。
  • 那不是 3d 数组。它是指向浮点数组的指针数组的指针数组。
  • 有趣的事实:最里面的数组没有初始化。
  • 将内存分配为width * height * depth 的一个大块。如果您需要将其归零(或初始化为值),请使用memset。然后索引为 3d 数组。

标签: c++ performance multidimensional-array memory-management


【解决方案1】:

我认为有两种选择:

  1. 加载具有数组结构的文件。
  2. 使用线程进行初始化,这种形式可以使用更多的cpu进行初始化。

您好。

【讨论】:

    【解决方案2】:

    当我想避免多维数组初始化但想要多维数组访问时,我正在做的一种方法是:

    #define IDX_3D(x, y, z, width, height) ((x) + (y) * (width) + (z) * (width) * (height))
    
    void main()
    {
        int width, height, depth;
        width = height = depth = 2;
        float* multi_array = new float[width * height * depth];
    
        multi_array[IDX_3D(1, 1, 1, width, height)] = 1.0f;
    }
    

    【讨论】:

      【解决方案3】:

      从 C++11 开始,您可以使用以下代码:

      int array[5][5][5] = {0};
      

      这将创建一个 3d 数组,其中包含 125 个用零填充的整数。 恕我直言,这是在堆栈上创建和初始化 3d 数组的最快(就代码行而言)方法。

      要在堆上创建一个(使用新的)其他答案似乎很好。

      当然你必须在之后用你的数据填充它,这需要一些时间,但它应该是可以接受的快。

      【讨论】:

      • 这需要在编译时知道大小。
      • 请注意OP需要创建一个"a large 3d array (~1GB)".
      【解决方案4】:

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

      如果您只创建一个大小为width * height * depth 的数组,并使用索引算法来访问它,效率会高得多。请记住,C++ 中“动态数组”的标准拼写方式是std::vector;这对你来说特别重要,因为vector 值初始化了它的所有元素(这对于float 意味着将它们初始化为.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]; }
      };
      

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

      速度更快的原因:

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

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

      【讨论】:

        猜你喜欢
        • 2015-02-03
        • 2022-01-13
        • 2016-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-14
        • 1970-01-01
        • 2011-01-11
        相关资源
        最近更新 更多