繁体   English   中英

大型二维静态数组和向量向量的内存使用

[英]Memory usage of large 2D static array and vector of vectors

我需要使用大型矩阵20000 * 20000进行机器学习项目。 当它作为静态数组实现时,它使用大约1.57 GB的内存。 如果使用向量向量实现它,则使用比静态数组(大约3.06 GB)更多的内存。 我无法弄清楚背后的原因。

阵列版本:

static double distanceMatrix[20000][20000] = {0};

矢量矢量:

vector<vector<double>> distanceMatrix(20000, vector<double> (20000));

我用它们来存储点之间的距离。

for (int i = 0; i < 20000; i++){
    for (int j = i+1; j < 20000; j++)
        distanceMatrix[i][j] = euclid_dist(pointVec[i], pointVec[j]);
}

我还观察到,当我使用数组版本时,内存使用量在嵌套循环期间逐渐增加。 但是,在使用向量向量时,内存使用量达到3.06 GB,然后嵌套循环开始。

我用Xcode调试导航器和Activity Monitor检查了内存使用情况。 提前致谢!

这是因为vector的内存分配策略,当达到其限制(依赖于实现)时可能是newsize = oldsize * const,另请参阅向量内存分配策略

首先,阵列不占用1,57 GB的内存。 因此测量存在问题。

试验静态数组

在Xcode中运行以下代码时,您会发现该数组的大小正好为3,2 Gb:

const size_t matsize=20000;
static double mat2D[matsize][matsize] = {0};  
cout<<"Double:             " << sizeof (double) <<endl;
cout<<"Array:              " << sizeof mat2D <<endl;
cout<<"                    " << sizeof(double)*matsize*matsize<<endl;
// ... then your loop

程序启动时,在进入循环之前报告的内存消耗仅为5,3MB,尽管静态数组已经存在。 循环结束后,报告的内存消耗量为1,57 Gb。 但仍然不是我们可以期待的3,2Gb。

您读取的内存消耗数字是进程使用的物理内存。 进程的剩余内存位于虚拟内存中,这个内存要大得多(在我的实验中为7 Gb)。

载体的实验

首先,让我们看看向量的近似内存大小,知道每个向量具有固定大小加上动态分配的变量大小(基于容量可以等于或大于实际存储在向量中的元素数)。 以下代码可以为您提供一些估算:

vector<vector<double>> mat2D(matsize, vector<double> (matsize));
cout<<"Vector (fixed part):" << sizeof (vector<double>)<<endl;
cout<<"Vector capacity:   " << mat2D[0].capacity()<<endl;
cout<<"       (variable):  " << sizeof(double)*mat2D[0].capacity()<<endl;
cout<<"       (total):     " << sizeof(double)*mat2D[0].capacity() + sizeof(mat2D[0])<<endl;
cout<<"Vector of vector:   " << (sizeof(double)*mat2D[0].capacity() + sizeof(mat2D[0]))*matsize+sizeof(mat2D)<<endl;
// then your loop 

运行此代码将显示存储向量向量所需的内存大约为3 Gb + 480 Kb开销(每个向量24个字节* 2001向量)。

在进入循环之前,我们会注意到已经使用了3 Gb的物理内存。 因此,与阵列版本相比,MacOS使用的物理内存是此动态版本的两倍。 这当然是因为分配过程需要预先真正访问更多内存:2000行中的每一行都需要单独的分配和初始化。

结论

两种方法中使用的整体虚拟内存没有那么不同。 我可以使用Xcode在调试模式下测量大约7Gb。 由于向量的额外480Kb开销,向量变体比以前使用了一点点。

macOS使用或多或少使用物理内存的策略很复杂,可能取决于许多因素(包括访问模式),目标是找到可用物理内存和交换成本之间的最佳权衡。

但物理内存使用量并不代表进程的内存消耗。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM