Tôi đang cố gắng phát triển sự hiểu biết tốt hơn về lượng bộ nhớ được cấp phát trên heap trong C++. Tôi đã viết một chương trình thử nghiệm nhỏ mà về cơ bản không làm gì khác ngoài việc điền vào một số vectơ 2D. Tôi đang chạy này trên một máy ảo Linux 64bit và sử dụng công cụ massif của valgrind để cấu hình bộ nhớ.Hiểu số lượng bộ nhớ C++ đang phân bổ
Môi trường tôi đang chạy thử nghiệm này trên: Linux VM đang chạy trong VirtualBox trên Win10. Cấu hình VM: Bộ nhớ cơ sở: 5248MB, 4CPU, nắp Ở mức 100%, VDI dạng đĩa (bộ nhớ được định vị động).
C++ bộ nhớ chương trình profiling test:
/**
* g++ -std=c++11 test.cpp -o test.o
*/
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main(int argc, char **arg) {
int n = stoi(arg[1]);
vector<vector<int> > matrix1(n);
vector<vector<int> > matrix2(n);
vector<vector<int> > matrix3(n);
vector<vector<int> > matrix4(n);
vector<vector<int> > matrix5(n);
vector<vector<int> > matrix6(n);
vector<vector<int> > matrix7(n);
vector<vector<int> > matrix8(n);
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix1[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix2[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix3[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix4[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix5[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix6[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix7[i].push_back(j);
}
}
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
matrix8[i].push_back(j);
}
}
}
tôi chạy kịch bản bash sau để giải nén hồ sơ bộ nhớ ở giá trị khác nhau của n
(test.o là chương trình trên, biên soạn với g ++ -std = C++ 11, g ++ là phiên bản 5.3.0)
valgrind --tool=massif --massif-out-file=massif-n1000.txt ./test.o 250
valgrind --tool=massif --massif-out-file=massif-n1000.txt ./test.o 500
valgrind --tool=massif --massif-out-file=massif-n1000.txt ./test.o 1000
valgrind --tool=massif --massif-out-file=massif-n2000.txt ./test.o 2000
valgrind --tool=massif --massif-out-file=massif-n4000.txt ./test.o 4000
valgrind --tool=massif --massif-out-file=massif-n8000.txt ./test.o 8000
valgrind --tool=massif --massif-out-file=massif-n16000.txt ./test.o 16000
valgrind --tool=massif --massif-out-file=massif-n32000.txt ./test.o 32000
này mang lại cho tôi kết quả như sau:
|--------------------------------|
| n | peak heap memory usage |
|-------|------------------------|
| 250 | 2.1 MiB |
| 500 | 7.9 MiB |
| 1000 | 31.2 MiB |
| 2000 | 124.8 MiB |
| 4000 | 496.5 MiB |
| 8000 | 1.9 GiB |
| 16000 | 6.2 GiB |
| 32000 | 6.1 GiB |
|--------------------------------|
Mỗi ma trận sẽ có kích thước n^2, tôi có tổng cộng 8 ma trận, do đó tôi dự kiến sử dụng bộ nhớ là khoảng f(n) = 8 * n^2
.
Câu hỏi 1 Từ n = 250 đến n = 8000, tại sao mức sử dụng bộ nhớ nhiều hay ít nhân với 4 ở n * = 2?
Từ n = 16000 đến n = 32000 điều gì đó rất lạ đang xảy ra vì valgrind thực sự báo cáo giảm bộ nhớ.
Câu hỏi 2 Điều gì đang xảy ra giữa n = 16000 và n = 32000, làm sao bộ nhớ heap có thể thấp hơn, trong khi lý thuyết có nhiều dữ liệu hơn nên được phân bổ?
Xem bên dưới đầu ra hình ảnh khối lượng cho n = 16000 và n = 32000.
Tôi đã [âm mưu kết quả của bạn] (http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiI4KnheMi8zMDAwMDAiLCJjb2xvciI6IiMyQjI0RkYifSx7InR5cGUiOjMsImVxIjpbWyIyNTAiLCIyLjEiXSxbIjUwMCIsIjcuOSJdLFsiMTAwMCIsIjMxLjIiXSxbIjIwMDAiLCIxMjQuOCJdLFsiNDAwMCIsIjQ5Ni41Il0sWyI4MDAwIiwiMTkwMCJdLFsiMTYwMDAiLCI2MjAwIl0sWyIzMjAwMCIsIjYxMDAiXV0sImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIjAiLCIzMjAwMCIsIjAiLCI4MDAwIl19XQ--) – YSC
Tôi muốn giới thiệu gắn thẻ câu hỏi này với trình biên dịch và nền tảng mà bạn đang chạy thử nghiệm của bạn trên.Các cơ chế nội bộ của cấp phát bộ nhớ được xác định bởi việc thực hiện của bạn, C++ làm cho ít áp đặt về chủ đề này. –
Sự hiểu biết của tôi là cách 'vector' quản lý bộ nhớ của nó phụ thuộc vào trình biên dịch ở một mức độ nào đó. Thông thường, việc quản lý bộ nhớ của 'vectơ' bao gồm một số mức độ phân bổ bộ nhớ trước cũng như mức độ dự đoán cho việc cấp phát bộ nhớ. hãy xem https://frogatto.com/2009/11/17/how-cs-vector-works-the-gritty-details/ –