计算向量的向量大小(以字节为单位)
Calculating size of vector of vectors in bytes
typedef vector<vector<short>> Mshort;
typedef vector<vector<int>> Mint;
Mshort mshort(1 << 20, vector<short>(20, -1)); // Xcode shows 73MB
Mint mint(1 << 20, vector<int>(20, -1)); // Xcode shows 105MB
short使用2字节,int使用4字节;请注意 1 << 20 = 2^20
;
我正在尝试提前(在纸面上)计算内存使用量,但我无法计算。
sizeof(vector<>) // = 24 //no matter what type
sizeof(int) // = 4
sizeof(short) // = 2
我不明白:mint
应该是 mshort
的两倍,但事实并非如此。当 运行 程序只有 mshort
初始化时 Xcode 显示 73MB 的内存使用; mint
105MB;
mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
mint.size() * min[0].size() * sizeof(int) * sizeof(vector<int>) // = 2013265920
//no need to use .capacity() because I fill vectors with -1
1006632960 * 2 = 2013265920
如何计算 2d std::vector
或 2d std::array
使用多少 space RAM。
我知道前面的尺寸,每行的列数相同。
向量的向量的内存使用量将是例如
// the size of the data...
mshort.size() * mshort[0].size() * sizeof(short) +
// the size of the inner vector objects...
mshort.size() * sizeof mshort[0] +
// the size of the outer vector object...
// (this is ostensibly on the stack, given your code)
sizeof mshort +
// dynamic allocation overheads
overheads
动态分配开销是因为 vector
在内部 new
存储元素的内存,并且出于速度原因,它们可能有固定大小的内存区域池等待新请求,所以如果 vector
有效地执行 new short[20]
- 数据需要 40 个字节 - 它可能以例如结束。 48 或 64。实现实际上可能需要使用一些额外的内存来存储数组大小,但对于 short
和 int
来说,在 delete[]
期间不需要循环调用析构函数的元素,所以一个好的实现将避免分配和无操作破坏行为。
虽然任何给定向量的实际数据元素在内存中都是连续的,因此如果您想减少开销,您可以更改代码以使用更少、更大的 vector
。例如,将 vector
与 (1 << 20) * 20
一起使用的开销可以忽略不计 - 然后您可以访问 [i * 20 + j]
而不是访问 [i][j]
- 您可以编写一个简单的 class 包装vector
为您完成此操作,最简单的方法是使用 v(i, j)
符号...
inline short& operator()(size_t i, size_t j) { return v_[i * 20 + j]; }
inline short operator()(size_t i, size_t j) const { return v_[i * 20 + j]; }
...尽管您可以通过让 v.operator[]
return 一个可以用 []
进一步索引的代理对象来支持 v[i][j]
。我敢肯定,如果您在 SO 中搜索有关多维数组的问题,将会有一些示例 - 我想我自己可能已经发布过一次这样的代码。
想要 vector<vector<x>>
的主要原因是内部 vector
的长度不同。
假设 glibc malloc:
每个内存块将为内存块header分配额外的8-16字节(2size_t)。对于 64 位系统,它将是 16 个字节。
见代码:
https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1110
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
. |
当每行添加 16 个字节时,它给了我大约 83886080。
26+16+ mshort.size(1048576) * (mshort[0].size(20)*sizeof(short(2)) + sizeof(vector(26))+header (16))
它给我大约 125829120 的整数。
但后来我重新计算了你的数字,看起来你是在 32 位...
- 短 75497472 即 ~73M
- long 117440512 即 ~112M
看起来与报告的非常接近。
使用容量而不是大小来获取#items 数量,即使它们与您的情况相同。
分配单个矢量大小行*列将为您节省 header*1048576 字节。
你的计算mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
完全错误。根据您的计算,mshort
需要 1006632960,即 960MiB,这是不正确的。
让我们忽略 libc 的开销,只关注 std::vector<>
的大小:
mshort
是 vector
个 1^20
项,每个 vector<short>
有 20 个项。
所以大小应该是:
mshort.size() * mshort[0].size() * sizeof(short) // Size of all short values
+ mshort.size() * sizeof(vector<short>) // Size of 1^20 vector<short>
+ sizeof(mshort) // Size of mshort itself, which can be ignored as overhead
计算出的大小为64MiB.
同mint,计算大小为104MiB.
所以 mint
只是 不是 mshort
的两倍大小。
typedef vector<vector<short>> Mshort;
typedef vector<vector<int>> Mint;
Mshort mshort(1 << 20, vector<short>(20, -1)); // Xcode shows 73MB
Mint mint(1 << 20, vector<int>(20, -1)); // Xcode shows 105MB
short使用2字节,int使用4字节;请注意 1 << 20 = 2^20
;
我正在尝试提前(在纸面上)计算内存使用量,但我无法计算。
sizeof(vector<>) // = 24 //no matter what type
sizeof(int) // = 4
sizeof(short) // = 2
我不明白:mint
应该是 mshort
的两倍,但事实并非如此。当 运行 程序只有 mshort
初始化时 Xcode 显示 73MB 的内存使用; mint
105MB;
mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
mint.size() * min[0].size() * sizeof(int) * sizeof(vector<int>) // = 2013265920
//no need to use .capacity() because I fill vectors with -1
1006632960 * 2 = 2013265920
如何计算 2d std::vector
或 2d std::array
使用多少 space RAM。
我知道前面的尺寸,每行的列数相同。
向量的向量的内存使用量将是例如
// the size of the data...
mshort.size() * mshort[0].size() * sizeof(short) +
// the size of the inner vector objects...
mshort.size() * sizeof mshort[0] +
// the size of the outer vector object...
// (this is ostensibly on the stack, given your code)
sizeof mshort +
// dynamic allocation overheads
overheads
动态分配开销是因为 vector
在内部 new
存储元素的内存,并且出于速度原因,它们可能有固定大小的内存区域池等待新请求,所以如果 vector
有效地执行 new short[20]
- 数据需要 40 个字节 - 它可能以例如结束。 48 或 64。实现实际上可能需要使用一些额外的内存来存储数组大小,但对于 short
和 int
来说,在 delete[]
期间不需要循环调用析构函数的元素,所以一个好的实现将避免分配和无操作破坏行为。
虽然任何给定向量的实际数据元素在内存中都是连续的,因此如果您想减少开销,您可以更改代码以使用更少、更大的 vector
。例如,将 vector
与 (1 << 20) * 20
一起使用的开销可以忽略不计 - 然后您可以访问 [i * 20 + j]
而不是访问 [i][j]
- 您可以编写一个简单的 class 包装vector
为您完成此操作,最简单的方法是使用 v(i, j)
符号...
inline short& operator()(size_t i, size_t j) { return v_[i * 20 + j]; }
inline short operator()(size_t i, size_t j) const { return v_[i * 20 + j]; }
...尽管您可以通过让 v.operator[]
return 一个可以用 []
进一步索引的代理对象来支持 v[i][j]
。我敢肯定,如果您在 SO 中搜索有关多维数组的问题,将会有一些示例 - 我想我自己可能已经发布过一次这样的代码。
想要 vector<vector<x>>
的主要原因是内部 vector
的长度不同。
假设 glibc malloc: 每个内存块将为内存块header分配额外的8-16字节(2size_t)。对于 64 位系统,它将是 16 个字节。 见代码: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1110
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
. |
当每行添加 16 个字节时,它给了我大约 83886080。
26+16+ mshort.size(1048576) * (mshort[0].size(20)*sizeof(short(2)) + sizeof(vector(26))+header (16))
它给我大约 125829120 的整数。
但后来我重新计算了你的数字,看起来你是在 32 位...
- 短 75497472 即 ~73M
- long 117440512 即 ~112M
看起来与报告的非常接近。
使用容量而不是大小来获取#items 数量,即使它们与您的情况相同。
分配单个矢量大小行*列将为您节省 header*1048576 字节。
你的计算mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
完全错误。根据您的计算,mshort
需要 1006632960,即 960MiB,这是不正确的。
让我们忽略 libc 的开销,只关注 std::vector<>
的大小:
mshort
是 vector
个 1^20
项,每个 vector<short>
有 20 个项。
所以大小应该是:
mshort.size() * mshort[0].size() * sizeof(short) // Size of all short values
+ mshort.size() * sizeof(vector<short>) // Size of 1^20 vector<short>
+ sizeof(mshort) // Size of mshort itself, which can be ignored as overhead
计算出的大小为64MiB.
同mint,计算大小为104MiB.
所以 mint
只是 不是 mshort
的两倍大小。