C++ 为什么我们需要使用folly::fbvector而不是std::vector和分配器,它们最初会保留较大的未限制区域?

C++ 为什么我们需要使用folly::fbvector而不是std::vector和分配器,它们最初会保留较大的未限制区域?,c++,memory-management,vector,posix,folly,C++,Memory Management,Vector,Posix,Folly,众所周知,如果我们将元素推回到std::vector,并且如果在向量中分配的整个内存被占用,那么std::vector将保留当前内存大小的2倍(以2倍大小分配新内存),调整向量大小并将旧数据复制到新内存 我们可以对它进行优化,Facebook在folly库中做到了这一点(FBVector是Facebook对std::vector的一个改进实现,它对可重定位类型和jemalloc进行了特殊的优化) 也就是说,当vector没有足够的内存来推回新元素时,我们会分配更多内存,但不会增加2倍(在不同的次

众所周知,如果我们将元素推回到
std::vector
,并且如果在向量中分配的整个内存被占用,那么
std::vector
将保留当前内存大小的2倍(以2倍大小分配新内存),调整向量大小并将旧数据复制到新内存

我们可以对它进行优化,Facebook在folly库中做到了这一点(FBVector是Facebook对std::vector的一个改进实现,它对可重定位类型和jemalloc进行了特殊的优化)

也就是说,当
vector
没有足够的内存来推回新元素时,我们会分配更多内存,但不会增加2倍(在不同的次数中:1.3-1.5倍)

说明:

下面的图形解算器显示,选择k=1.5(蓝线) 允许在4次重新分配后重新使用内存,选择k=1.45(红色 行)允许在3次重新分配后重新使用内存,并选择k=1.3 (黑线)只允许在2次重新分配后重新使用

但是,为什么我们需要使用
folly::fbvector
而不是
std::vector
与我们的自定义分配器一起使用(如下所示:),或者在linux中使用相同的分配器,其中:

  • std::vector::reserve()
    -最初保留较大的虚拟地址未提交区域(分配WMA,但不在PT中分配任何PTE),例如,最初分配16 GB的虚拟区域,每次缺少内存时提交内存(分配PTE-分配物理区域)等于向量大小的1倍
  • std::vector::resize()
    -然后只提交一批新的页面,只在PT中分配新的PTE,而不重新分配已经使用的内存,也不将数据从旧内存复制到新内存
总体

与folly::vector相比,这种方法具有较大的未提交区域的优势:
folly::vector
我们总是只分配新的内存部分,从不复制旧数据。


folly::vector
方法优于
std::vector
有时我们不需要分配新内存,但应始终将旧数据复制到新内存中。

这是特定于实现的。GCC库的分配量是原来的两倍,但Visual C++没有。我相信,它也使用1.5,但不确定

我相信,
folly
应该是操作系统无关的,您的方法是Windows/Linux特定的


如果您仔细选择类型,从旧向量移动到新向量的对象应该不会太糟糕-也就是说,使用
std::unique\u ptr
作为数据类型。

VC可能使用黄金比例(1.61…),这是随着大小变大的理论正确比例。请参阅。不,MSVC使用1.5。自从微软授权了Dinkumware实现以来,它一直在使用@sfjac@SergeyA非常感谢。是的,最有可能的是跨平台和跨硬件使用。但是为什么他们没有在K-optimization之外添加对Win/Linux非常普通的操作系统非常有效的优化-我不明白。智能指针仅用于大型对象是有意义的,但不能用于大量大型对象(内存有限),并且向量(指向大型对象的指针数组)的内存重新分配问题永远不会发生。