64位计算机上的stl向量大小

Mar*_*rkB 0 c++ stl vector

我有一个将使用数百万向量的应用程序.

似乎std :: vector的大多数实现使用4个指针(_First,_Last,_End和_Alloc),它们在64位机器上消耗32个字节.对于矢量的大多数"实际"用例,可以分别使用单个指针和两个"unsigned int"字段来存储当前大小和分配的大小.忽略支持自定义分配的潜在挑战(而不是假设分配必须通过全局new&delete运算符),似乎可以构建一个仅使用16个字节的STL兼容向量类(或者最坏的24个字节到支持_Alloc指针).

在我开始编写代码之前,1)是否存在我应该注意的任何陷阱; 2)是否存在开源实现?

Bil*_*eal 5

你可以完成这样的事情 - 但是你不可能获得那么多.

首先,有性能方面.你正在交换内存消耗的时间.无论你保存什么内存,都要通过必须对每次调用进行加法和乘法来抵消end(好吧,如果它是sizeof(vector<t>::value_type) == 1可以优化乘法的向量).请注意,大多数手写的循环代码end都会在每次循环迭代时调用.在现代CPU上,它实际上将成为一个重大胜利,因为它允许处理器在缓存中保留更多内容; 除非内循环中的那些额外指令强制处理器过于频繁地交换指令缓存中的东西)

此外,由于以下原因,在向量中的总体内存使用方面,内存节省可能很小:

  • 内存管理器开销.来自内存管理器的每个分配(当然需要哪个向量)将在大多数内存管理器实现中自己添加16-24字节的开销.(假设类似dlmalloc(UNIX/Linux/etc.)或RtlHeap(Windows))
  • 过度配置负载.为了在结束时实现分摊的常量插入和移除,当向量调整大小时,它将调整大小到向量中数据大小的某个倍数.这意味着典型的内存容量向量分配足以使1.6(MSVC++)或2(STLPort,libstdc ++)乘以实际存储在向量中的元素数量.
  • 对齐限制.如果要将这些向量放入数组(或其他向量),请记住该向量的第一个成员仍然是指向已分配内存块的指针.这个指针通常需要8字节对齐 - 所以你保存的4个字节会丢失到数组中的结构填充.

我现在使用vector的简单实现.如果您通过内存分析器运行代码,并发现通过摆脱这些指针可以节省大量资金,那么您可能不会实现自己的优化类来满足您的性能特征,而不是依赖于内置的矢量实现.(一个这样的优化类的例子是std::string在那些实现小字符串优化的平台上)

(注意:我所知道的唯一一个优化了Alloc指针的编译器是VC11,它还没有发布.虽然Nim说libstdc ++的当前预发布版本也是如此......)