C++ 4d 数组内存释放很慢
Posted
技术标签:
【中文标题】C++ 4d 数组内存释放很慢【英文标题】:C++ 4d array memory deallocation is slow 【发布时间】:2017-05-01 14:32:51 【问题描述】:我的代码中有一个 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 parallel,一切正常。但是很慢……
【问题讨论】:
您正在运行发布版本吗?我已经看到了 Visual Studio 中的调试版本的执行时间比发布版本长 100 倍的情况,因为在调试版本中会发生额外的检查,例如堆损坏测试。还要考虑一维数组。 为了爱宇宙中所有邪恶的事物,请使用std::vector
和适当的智能指针。
@CaptainObvlious 我做到了并不快
@drescherjm 我将更改为发布,我不知道速度因素在内存分配中如此疯狂,但是我也在尝试进行 TDD 单元测试并在调试模式下运行它们,所以我想也许有人有更好的方法。一维数组当然意味着索引游戏,但也许这是要走的路。谢谢
那个代码比好莱坞星光大道的星星还多。
【参考方案1】:
使用指向...的指针是个坏主意,因为它会大量分割您的数据。
我会创建一个类来管理索引转换并使用一维数组,它有点复杂但会更快。
无论如何,一个技巧:没有什么可以阻止您使用指向内存中非稀疏区域的指针(您预先分配的一维数组)构建您的 int****,然后将其用作 4D 数组。
【讨论】:
Richard 的评论是正确的。我知道这很糟糕,我在寻求更好的方法 @RichardHodges 这将问题归为“过于宽泛”的类别。【参考方案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
【讨论】:
为什么是auto totalSize() const -> std::size_t
而不是std::size_t totalSize() const
?有没有我想念的微妙之处?
@YSC 这两种形式在 c++11 中是等价的
我知道,但你为什么要使用奇怪的形式auto -> type
,在那里你可以使用我们几十年来都习惯的形式?无论如何,我并不是说这是批评,我只是好奇。
@YSC 我出于习惯使用自动表单,如果我碰巧需要它添加尾随返回类型(就像我在这种情况下所做的那样,因为我在定义之前调用了函数)
@YSC 虽然你可以看到我不一致:)【参考方案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 数组的索引。
p>int * fourDimArrayAsOneDim = new int[H*I*J*K];
fourDimArrayAsOneDim[indexFromIndices(h, i, j, k)] = 0;
delete [] fourDimArrayAsOneDim;
【讨论】:
这是不合法的 c++ 更正以正确编译并提供一些选项。道歉。以上是关于C++ 4d 数组内存释放很慢的主要内容,如果未能解决你的问题,请参考以下文章