gpt4 book ai didi

c++ - 在 C++ 中分配一个大内存块

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:53:57 24 4
gpt4 key购买 nike

我正在尝试为浮点值的 C++ 中的 3D 矩阵分配一个大内存块。它的尺寸是 44100x2200x2。这应该正好占用 44100x2200x2x4 字节的内存,大约 7.7gb。我正在使用 Ubuntu 的 64 位 x86 机器上使用 g++ 编译我的代码。当我使用 htop 查看进程时,我看到内存使用量增长到 32gb 并立即被终止。我的内存计算有误吗?

这是我的代码:

#include <iostream>

using namespace std;
int main(int argc, char* argv[]) {
int N = 22000;
int M = 44100;
float*** a = new float**[N];
for (int m = 0; m<N; m+=1) {
cout<<((float)m/(float)N)<<endl;
a[m] = new float*[M - 1];
for (int n = 0; n<M - 1; n+=1) {
a[m][n] = new float[2];
}
}
}

编辑:我的计算不正确,我分配的内存接近 38GB。我现在修改代码以分配 15gb。

#include <iostream>

using namespace std;
int main(int argc, char* argv[]) {
unsigned long N = 22000;
unsigned long M = 44100;
unsigned long blk_dim = N*(M-1)*2;
float* blk = new float[blk_dim];
unsigned long b = (unsigned long) blk;

float*** a = new float**[N];
for (int m = 0; m<N; m+=1) {
unsigned long offset1 = m*(M - 1)*2*sizeof(float);
a[m] = new float*[M - 1];
for (int n = 0; n<M - 1; n+=1) {
unsigned long offset2 = n*2*sizeof(float);
a[m][n] = (float*)(offset1 + offset2 + b);
}
}
}

最佳答案

您忘记了一维,以及分配内存的开销。显示的代码在三维空间中分配内存的效率非常低,导致开销太大。

float*** a = new float**[N];

这将分配大约 22000 * sizeof(float **),大约 176kb。可以忽略不计。

a[m] = new float*[M - 1];

此处的单个分配将为 44099 * sizeof(float *),但您将获得其中的 22000 个。 22000 * 44099 * sizeof(float *),或大约 7.7gb 的额外内存。这是您停止计数的地方,但您的代码尚未完成。它还有很长的路要走。

a[m][n] = new float[2];

这是一次8字节的分配,但是这个分配会做22000 * 44099次。那是 另一个 7.7gb 被冲进了下水道。您现在大约有超过 15 GB 的应用程序所需内存需要分配。

但是每个分配都不是免费的new float[2] 需要更多 8 个字节。您的 C++ 库必须在内部跟踪每个单独分配的 block ,以便可以通过 delete 回收它。最简单的基于链表的堆分配实现需要一个前向指针、一个后向指针以及分配 block 中​​有多少字节的计数。假设不需要为了对齐目的而填充任何内容,那么在 64 位平台上,每次分配至少有 24 字节的开销。

现在,由于您的第三个维度分配了 22000 * 44099 个分配,第二个维度分配了 22000 个分配,第一个维度分配了一个:如果我指望手指,这将需要 (22000 * 44099 + 22000 + 1) * 24,或另外 22 GB 的内存,只是为了消耗最简单、最基本的内存分配方案的开销。

如果我的计算正确的话,使用最简单、可能的堆分配跟踪,我们现在最多需要大约 38 GB 的 RAM。您的 C++ 实现可能会使用稍微更复杂的堆分配逻辑,开销更大。

去掉 new float[2]。计算矩阵的大小,新建 一个 7.7gb block ,然后计算其余指针应指向的位置。此外,为矩阵的第二维分配一 block 内存,并计算第一维的指针。

您的分配代码应该恰好执行三个 new 语句。一个为第一维指针,一个为第二维指针。还有一个用于构成第三维度的大量数据。

关于c++ - 在 C++ 中分配一个大内存块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52068410/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com