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



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

然而,更多的分析显示,所有的时间(实际上是在我厌倦等待之前的几十分钟(都花在了pool_allocator::ordered_free((中。我在一个简单的测试程序中重现了同样的行为(尽管没有那么极端(,事实上,当一大组构造的向量将它们的内存返回到单例池时,函数在返回之前会挂起很长一段时间。

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

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

根据您的问题,我假设

  • 这只是一个功能
  • 矢量的大小是有限的(你说它很小(
  • 函数的递归调用频率不高

如果是这种情况,请考虑使用堆栈分配的内存,而不是动态分配的内存。您可以不使用vector,而是使用std::array<>和一些大小指示符(如果存储的类型是可构造的(或一些固定大小和新位置的原始内存缓冲区,或者将后者封装到分配器类中,以便将vector与该分配器类一起使用。

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

最新更新