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

C+中的自定义池分配器+;除了boost::pool 我在C++中有一个使用场景,其中一个函数多次调用,创建了一些本地的、小的但动态大小的向量。在分析了我的程序之后,我注意到在std::vector::free()中花费了过多的时间。对于这样一个问题,一个自然的(C++-esque)解决方案似乎是将默认分配器切换到更适合我的使用场景的位置。特别是,在这里使用内存池策略似乎是有意义的。然而,到目前为止,boost::pool_alloc只不过是个麻烦。我已经让它工作了,但是虽然在我的小但经常调用的函数(我们将调用该函数f())中分配更快,但它会导致调用f()的函数在返回之前挂起很长一段时间,c++,boost,stl,malloc,allocator,C++,Boost,Stl,Malloc,Allocator,然而更多的分析表明,所有的时间(在我厌倦等待之前的几十分钟)都花在了pool_allocator::ordered_free()中。我在一个简单的测试程序中重现了同样的行为(虽然没有那么极端),事实上,当大量构造向量将其内存返回到单例池时,函数在返回之前会挂起很长一段时间 如果有人知道避免这种行为的方法,或者其他不受这种问题困扰的C++池分配器,我将非常感激!p> 我自己也写过几次,一旦一切进展顺利,分配和释放就会非常快。 1.按大小创建池的映射。 2.每个池都有一个双链接的块列表。 3.每个区

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


如果有人知道避免这种行为的方法,或者其他不受这种问题困扰的C++池分配器,我将非常感激!p> 我自己也写过几次,一旦一切进展顺利,分配和释放就会非常快。 1.按大小创建池的映射。 2.每个池都有一个双链接的块列表。 3.每个区块前后都有额外空间,用于列表节点和所有者池参考、大小检查等 4.分配速度很快,因为您只需查找大小>=块大小的第一个池,然后取消列出第一个条目。 5.释放速度很快,因为内存块中有一个指向池的指针,所以只需重新列出它。 6.您可以在启动时创建一组空池。然后,在每个alloc上,首先尝试从池中取消列出。如果失败,则改为malloc()。释放块后,将其添加回池中,而不是释放它。 7.一旦你的应用程序运行稳定,所有的Alloc都会直接从池链接列表中出来,免费的会直接回到那里。。。超快。


8.当程序退出时,释放()池中的所有内存

从你的问题来看,我认为

  • 这只是一个函数
  • 向量的大小是有限的(你说它很小)
  • 函数的递归调用不太频繁

如果是这样,考虑使用堆栈分配的内存,而不是动态分配的内存。您可以不使用vector,而是使用

std::array
和一些大小指示符(如果存储的类型是可构造的)或一些固定大小和位置的原始内存缓冲区,或者将后者包装到一个分配器类中,以便将vector与该分配器类一起使用


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

reserve
-ing正确设置确实有帮助(如果您还没有)。嗨,Justin,是的,我已经在保留向量了。问题是,我在函数调用时知道每个向量的大小(即它们没有增长),但在编译时不知道,所以它们仍然是动态的。存储的类型是可构造的(它的大小)。但是,我不能真正使用堆栈分配的存储,因为场景比我最初介绍的要复杂一点。特别是,虽然在每个函数调用中创建了大量向量,并且大多数向量在函数返回之前被销毁,但有少量向量确实被合并到其他堆对象中并退出函数。我想我可以复制这些向量(而不是移动)。我想避免编写自己的分配器,但这可能是最好的方法。如果您事先知道哪些向量会移动到堆对象,可以使用标准分配器。