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中使用相同的分配器,其中:
-最初保留较大的虚拟地址未提交区域(分配WMA,但不在PT中分配任何PTE),例如,最初分配16 GB的虚拟区域,每次缺少内存时提交内存(分配PTE-分配物理区域)等于向量大小的1倍std::vector::reserve()
-然后只提交一批新的页面,只在PT中分配新的PTE,而不重新分配已经使用的内存,也不将数据从旧内存复制到新内存std::vector::resize()
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非常普通的操作系统非常有效的优化-我不明白。智能指针仅用于大型对象是有意义的,但不能用于大量大型对象(内存有限),并且向量(指向大型对象的指针数组)的内存重新分配问题永远不会发生。