除了boost :: pool之外,C ++中的自定义池化分配器

时间:2013-02-26 06:53:34

标签: c++ boost stl malloc allocator

我在C ++中有一个使用场景,其中我多次调用的函数会创建一些局部的,小但动态大小的向量。在对我的程序进行概要分析后,我注意到在std :: vector :: free()中花费了过多的时间。这种问题的自然(C ++ - esque)解决方案似乎是将默认分配器切换为更适合我的使用场景的东西。特别是,使用内存池策略似乎在这里有意义。但是,到目前为止,boost :: pool_alloc已经不过是麻烦了。我已经让它工作了,但是虽然我的小但经常调用的函数(我们称之为函数f())的分配速度更快,但它会导致调用f()的函数在返回之前挂起< em>很长时间。

然而,更多的分析表明,所有的时间(在我厌倦了等待之前几十分钟)都花在了pool_allocator :: ordered_free()上。我在一个简单的测试程序中重现了这种相同的行为(虽然不是极端),看来,实际上,当一大组构造向量将其内存返回到单例池时,该函数在返回之前会挂起很长时间

如果有人知道避免这种行为的方法,或者没有遇到这种问题的另一个C ++池分配器,我会非常感激!

2 个答案:

答案 0 :(得分:0)

我已经写了几次,一旦一切进展,分配和释放是超级快的。 1.按大小创建池映射。 2.每个池都有一个双向链接列表。 3.对于列表节点和所有者池引用,大小检查等,每个块在前面和后面都有额外的空间 4.分配速度很快,因为您只需要查找大小为&gt; =您的块大小的第一个池并取消列出第一个条目。 5.解除分配很快,因为你在内存块中有一个指向池的指针,所以你所要做的就是重新分配它。 6.您可以在启动时创建一堆空池。然后,在每个alloc上,首先尝试从池中取消列表。如果失败,则改为malloc()。释放块后,将其添加回池中而不是释放它。 7.一旦你的应用程序运行稳定,所有的分配将直接来自池链接列表,并且释放将立即返回...超快速。 8.当程序退出时,Free()池中的所有内存。

答案 1 :(得分:0)

从你的问题来看,我认为

  • 只有一个功能
  • 向量的大小是有限的(你说它很小)
  • 该函数不会经常递归调用

如果是这种情况,请考虑使用堆栈分配的内存而不是动态分配的内存。你可以通过不使用向量但使用std::array<>和一些大小指示符(如果存储的类型是可构造的)或一些固定大小和位置new的原始内存缓冲区,或将后者包装到allocator类中来使用矢量与该分配器类。

如果您的性能问题仅限于如此小的代码区域,我不会使用像boost :: pool这样的通用内存管理工具,而是针对当前的情况推出一些非常专业的内容。