繁体   English   中英

计算向量的向量大小(以字节为单位)

[英]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使用多少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结尾。实现可能实际上需要使用一些额外的内存来存储数组大小,尽管shortintint并不需要遍历元素调用在delete[]期间使用析构函数,因此良好的实现将避免这种分配和no-op破坏行为。

但是,任何给定向量的实际数据元素在内存中都是连续的,因此,如果要减少开销,可以更改代码以使用更少,更大的vector 例如,使用一个(1 << 20) * 20 vector开销可以忽略不计-然后可以访问[i * 20 + j]而不是访问[i][j] [i * 20 + j] -您可以编写一个简单的类来包装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[]返回一个可以用[]进一步建立索引的代理对象来支持v[i][j] [] 我确定如果您在多维数组上搜索问题,将有一些示例-认为我自己可能曾经发布过此类代码。

想要vector<vector<x>>主要原因是当内部vector s的长度变化时。

假设glibc malloc:每个内存块将为内存块头分配额外的8-16字节(2 size_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
  • 长117440512即〜112M

看起来非常接近报告的那些。

即使您的情况相同,也请使用容量而非大小来获取#items号。

分配单个向量大小的行*列将节省标题* 1048576字节。

您的计算mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960是完全错误的。 根据您的计算, mshort需要1006632960,即960MiB,这是不正确的。

让我们忽略的libc的开销,并且仅仅关注std::vector<>的尺寸: mshort是一个vector1^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

暂无
暂无

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

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