【问题标题】:boost::pool default number of chunksboost::pool 默认块数
【发布时间】:2015-08-25 15:21:50
【问题描述】:

我试图了解 boost::pool 块预分配的策略。我阅读了 thisthis boost 文档,但我仍然不清楚是否可以请求特定的初始实例化池时预分配的块数。当我说“块”时,我的意思是块 = sizeof(SomeType) 例如,我做了这个测试:

Foo.h

  class Foo
  {
     public:
       typedef MAllocator<float>        FloatPoolAllocator;
       typedef std::shared_ptr<boost::pool<> >  FloatPoolSP;
       static FloatPoolSP                      _floatPoolSP;
       static FloatPoolAllocator               _floatAllocator;

       std::vector<float, FloatPoolAllocator> data1;

       std::vector<float, FloatPoolAllocator> data2;

       std::vector<float, FloatPoolAllocator> data3;

   };

Foo.cpp

    std::shared_ptr<boost::pool<> >   Foo::_floatPoolSP = std::shared_ptr<boost::pool<> >(new boost::pool<>(sizeof(uint8_t), 65536)); 

   MAllocator<float> Foo::_floatAllocator = MAllocator<float>(_floatPoolSP);

  Foo::Foo()
  {

    data1 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
    data2 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
    data3 = std::vector<float, FloatPoolAllocator>(_floatAllocator);

  }

现在,我希望我的进程内存至少是指定 boost::pool 大小的两倍,因为我还在不同地方分配了其他池,块大小从 4 到 16 mb 不等。仅这个池就是 64 mb 并查看 Windows 任务管理器(不是调查内存的最佳工具......)我看到总内存消耗约为 78 mb。它让我认为 boost::pool 没有分配块大小65536,至少不是第一次。这是真的吗?如果是,这是否意味着我需要包装自己的池以允许这样的功能?因为我没有在池中找到任何允许另一种方式的东西这样做。

PS:如果我删除池,我会看到进程使用的内存量几乎相同,这可能再次意味着 boost::pool 分配了非常小的块。

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    我试图理解 boost::pool 块的策略 预分配。我读过这个和这个提升文档,但它仍然不是 我清楚是否可以请求特定的初始数量 实例化池时预分配的块。

    不,这是不可能的,除非您编写自己的分配器,这可能会保留一些默认值。

    这里解释了简单隔离存储的关键/本质(摘自here):

    简单的隔离存储也非常快。在最简单的 在这种情况下,内存分配只是从 空闲列表,O(1) 操作。在空闲列表为空的情况下, 可能必须获取和分割另一个块,这将 导致摊销的 O(1) 时间。内存释放可能很简单 就像将该块添加到空闲列表的前面一样,这是一个 O(1) 操作。 但是,简单隔离存储的更复杂用途可能 需要一个排序的空闲列表,这使得释放 O(N)。

    从这里你可以看到,当没有空闲块存在时(即空闲列表为空时),boost pool 会根据需要分配内存。因此,可能不会发生预分配(或很少发生),但是一旦分配了某些东西,释放和重新分配就会非常快(因为基本上在池超出范围之前它永远不会真正释放)。

    那我不明白他们为什么提供那个“nextsize”参数。是否至少保证下一个块分配等于那个大小?

    分配器使用适用标签类型的 singleton_pool 实例,具体取决于分配器类型。 Singleton_pool 实例化了一个 pool 的实例,从 pools 源中可以看出:

    • ma​​x_size 是分配给一个块的最大块数。
    • next_size 是第一次请求对象需要分配内存的块数。
    • 另一个参数(requested_size)是从sizeof(T)中获得的,即请求对象的大小。

    PS:如果我删除池,我会看到进程使用的内存量几乎相同,这可能再次意味着 boost::pool 分配了非常小的块。

    是的,它使用参数next_size进行第一次分配,可能不会大于max_size

    【讨论】:

    • 那我不明白他们为什么提供那个“nextsize”参数。是否至少保证下一个块分配等于那个大小?
    • 查看我的改编答案。
    猜你喜欢
    • 1970-01-01
    • 2013-04-03
    • 2012-01-07
    • 2013-05-16
    • 2011-01-21
    • 2018-02-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多