简体   繁体   English

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

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

I need to use large matrix 20000 * 20000 for a machine learning project. 我需要使用大型矩阵20000 * 20000进行机器学习项目。 When it is implemented as static array, it uses approximately 1.57 GB of memory. 当它作为静态数组实现时,它使用大约1.57 GB的内存。 If it is implemented with vector of vectors it uses much more memory then the static array (approximately 3.06 GB). 如果使用向量向量实现它,则使用比静态数组(大约3.06 GB)更多的内存。 I could not figure out the reason behind it. 我无法弄清楚背后的原因。

Array version: 阵列版本:

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

Vector of vectors: 矢量矢量:

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

I used them to store the distances between points. 我用它们来存储点之间的距离。

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

I also observed that when I used array version memory usage increases gradually during the nested loop. 我还观察到,当我使用数组版本时,内存使用量在嵌套循环期间逐渐增加。 However, while using vector of vectors, memory usage reaches 3.06 GB then nested loop starts. 但是,在使用向量向量时,内存使用量达到3.06 GB,然后嵌套循环开始。

I checked the memory usage with Xcode debug navigator and Activity Monitor. 我用Xcode调试导航器和Activity Monitor检查了内存使用情况。 Thanks in advance! 提前致谢!

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

First of all the array doesn't take 1,57 GB of memory. 首先,阵列不占用1,57 GB的内存。 So there is an issue with the measurement. 因此测量存在问题。

Experiment with the static array 试验静态数组

When running the following code in Xcode, you'll find out that the array is exactly 3,2 Gb in size: 在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

When the programme starts, its reported memory consumption is only 5,3MB before entering into the loop, although the static array is already there. 程序启动时,在进入循环之前报告的内存消耗仅为5,3MB,尽管静态数组已经存在。 Once the loop finished, the reported memory consumption is 1,57 Gb as you explained. 循环结束后,报告的内存消耗量为1,57 Gb。 But still not the 3,2Gb that we could expect. 但仍然不是我们可以期待的3,2Gb。

The memory consumption figure that you read is the physical memory used by your process. 您读取的内存消耗数字是进程使用的物理内存。 The remaining memory of the process is in the virtual memory, which is much larger (7 Gb during my experiment). 进程的剩余内存位于虚拟内存中,这个内存要大得多(在我的实验中为7 Gb)。

Experiment of the vector 载体的实验

First, let's look at the approximate memory size of the vector, knowing that each vector has a fixed size plus a dynamically allocated variable size (based on the capacity which can be equal or greater than the number of elements actually stored in the vector). 首先,让我们看看向量的近似内存大小,知道每个向量具有固定大小加上动态分配的变量大小(基于容量可以等于或大于实际存储在向量中的元素数)。 The following code can give you some estimates: 以下代码可以为您提供一些估算:

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 

Running this code will show that the memory required to store your vector of vector is about 3,2 Gb + 480 Kb overhead (24 bytes per vector * 2001 vectors). 运行此代码将显示存储向量向量所需的内存大约为3 Gb + 480 Kb开销(每个向量24个字节* 2001向量)。

Before entering the loop, we will notice that already 3 Gb of physical memory is used. 在进入循环之前,我们会注意到已经使用了3 Gb的物理内存。 So MacOS uses twice the physical memory for this dynamic version compared to the array version. 因此,与阵列版本相比,MacOS使用的物理内存是此动态版本的两倍。 This is certainly because the allocation process requires to really access more memory upfront: each of the 2000 lines requires a separate allocation and initialization. 这当然是因为分配过程需要预先真正访问更多内存:2000行中的每一行都需要单独的分配和初始化。

Conclusion 结论

The overall virtual memory used in the two approaches is not that different. 两种方法中使用的整体虚拟内存没有那么不同。 I could measure around 7Gb running it in debug mode with Xcode. 我可以使用Xcode在调试模式下测量大约7Gb。 The vector variant uses a little bit more than previously due to the extra 480Kb overhead for vectors. 由于向量的额外480Kb开销,向量变体比以前使用了一点点。

The strategy used by macOS for using more or less physical memory is complex and may depend on many factors (including the access patterns), the goal being to find the best tradeoff between physical memory available and cost of swapping. macOS使用或多或少使用物理内存的策略很复杂,可能取决于许多因素(包括访问模式),目标是找到可用物理内存和交换成本之间的最佳权衡。

But the physical memory usage is not representative of the memory consumption by the process. 但物理内存使用量并不代表进程的内存消耗。

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

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