簡體   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