C ++ 4d数组内存释放很慢

时间:2016-12-15 21:18:12

标签: c++ optimization memory-management

我的代码中有一个4D矩阵用于解决一些数学问题

int**** Sads = new int***[inputImage->HeightLines];
for (size_t i = 0; i < inputImage->HeightLines; i++)
{
    Sads[i] = new int**[inputImage->WidthColumns];
    for (size_t j = 0; j < inputImage->WidthColumns; j++)
    {
        Sads[i][j] = new int*[W_SIZE];
        for (size_t k = 0; k < W_SIZE; k++)
         {
              Sads[i][j][k] = new int[W_SIZE];
         }
    }
 }

//do something with Sads...

for (int i = 0; i < inputImage->HeightLines; i++)
        {
            int*** tempI = Sads[i];
            for (int j = 0; j < inputImage->WidthColumns; j++)
            {
                int** tempJ = tempI[j];
                for (int k = 0; k < W_SIZE; k++)
                {
                    delete[] tempJ[k];
                }
                delete[] Sads[i][j];
            }
            delete[] Sads[i];
        }
        delete[] Sads;

尺寸非常大WidthColumns = 2018,HeightLines = 1332,W_SIZE = 7,内存分配非常快但内存释放(删除)非常慢。
有没有办法优化它?
我厌倦了openMP,但是它抛出了无关的DLL错误,如果我删除了#pragma omp并行,一切正常。但是很慢......

3 个答案:

答案 0 :(得分:6)

使用指向...的指针是个坏主意,因为它会对你的数据进行大量分割。

我会创建一个类来管理索引变换并使用1D数组,它会更复杂但会更快。

无论如何,一个诀窍:没有什么能阻止你使用指向内存区域的指针构建你的int ****,这个区域不是稀疏的(你预分配的1D数组),然后将它用作4D数组。

答案 1 :(得分:2)

我可能倾向于使用std::vector。现在为我处理内存分配(在一次分配/释放中),我获得了免费的复制/移动语义。

我所要做的就是提供偏移计算:

#include <vector>
#include <cstddef>

struct vector4
{
    vector4(std::size_t lines, std::size_t columns)
            : lines_(lines), columns_(columns)
    , storage_(totalSize())
    {}

    auto totalSize() const -> std::size_t
    {
        return lines_ * columns_ * w_size * w_size;
    }

    int* at(std::size_t a)
    {
        return storage_.data() + (a * columns_ * w_size * w_size);
    }

    int* at(std::size_t a, std::size_t b)
    {
        return at(a) + (b * w_size * w_size);
    }

    int* at(std::size_t a, std::size_t b, std::size_t c)
    {
        return at(a, b) + (c * w_size);
    }

    int& at(std::size_t a, std::size_t b, std::size_t c, std::size_t d)
    {
        return *(at(a, b, c) + d);
    }

private:

    std::size_t lines_, columns_;
    static constexpr std::size_t w_size = 32; // ?
    std::vector<int> storage_;

};

int main()
{
    auto v = vector4(20, 20);
    v.at(3, 2, 5, 1) = 6;
    // other things

    // now let it go out of scope
}

答案 2 :(得分:-3)

唐氏选民,我更正了这段代码,在修正之前这个代码确实很糟糕。是否还有值得投票的事情?如果是这样,说什么。如果没有,请重新考虑您的投票。

创建,使用和删除4D数组的正确方法是这样,使用语句组的闭包来删除自动变量。

{
    const int H = 10;
    const int I = 10;
    const int J = 10;
    const int K = 10;
    int h = 0;
    int i = 0;
    int j = 0;
    int k = 0;
    int fourDimArray [H][I][J][K];
    fourDimArray[h][i][j][k] = 0;
}

如果你需要动态分配,那么使用STL的列表或矢量类,或者使用类似的东西,使用内联方法从4D数组索引计算1D数组的索引,如果你需要炽热的话速度。

int * fourDimArrayAsOneDim = new int[H*I*J*K];
fourDimArrayAsOneDim[indexFromIndices(h, i, j, k)] = 0;
delete [] fourDimArrayAsOneDim;