我目前有大量的多线程服务器应用程序,我正在四处寻找一个好的多线程内存分配器。
到目前为止,我在:
- 孙梅
- 谷歌的 tcmalloc
- 英特尔的线程构建块分配器
- 埃默里·伯杰的宝藏
根据我的发现,hoard 可能是最快的,但我在今天之前没有听说过它,所以我怀疑它是否真的像看起来那么好。任何人都有尝试这些分配器的个人经验吗?
我目前有大量的多线程服务器应用程序,我正在四处寻找一个好的多线程内存分配器。
到目前为止,我在:
根据我的发现,hoard 可能是最快的,但我在今天之前没有听说过它,所以我怀疑它是否真的像看起来那么好。任何人都有尝试这些分配器的个人经验吗?
我使用过 tcmalloc 并阅读了有关 Hoard 的信息。两者都有类似的实现,并且都实现了相对于线程/CPU 数量的大致线性性能扩展(根据各自站点上的图表)。
所以:如果性能真的非常重要,那么就进行性能/负载测试。否则,只需掷骰子并选择列出的一个(根据目标平台上的易用性加权)。
从trshiv 的链接来看,Hoard、tcmalloc 和 ptmalloc 的速度似乎都差不多。总体而言,tt 看起来 ptmalloc 为尽可能少地占用空间而优化,Hoard 为速度 + 内存使用的权衡而优化,而 tcmalloc 为纯速度而优化。
真正判断哪个内存分配器适合您的应用程序的唯一方法是尝试一些。提到的所有分配器都是由聪明的人编写的,并且将在一个特定的微基准测试或另一个上击败其他分配器。如果您的应用程序整天所做的只是在线程 A 中分配一个 8 字节块并在线程 B 中释放它,并且根本不需要处理任何其他事情,那么您可能会编写一个内存分配器来击败任何一个到目前为止列出的那些。它对其他很多事情都没有多大用处。:)
我在工作的地方有一些使用 Hoard 的经验(足以让我发现最近的 3.8 版本中解决的一个更模糊的错误是由于该经验而发现的)。这是一个非常好的分配器——但对你来说有多好取决于你的工作量。而且你必须为 Hoard 付费(尽管它并不太贵)才能在商业项目中使用它,而无需 GPL 对你的代码进行 GPL。
很长一段时间以来,经过轻微调整的 ptmalloc2 一直是 glibc 的 malloc 背后的分配器,因此它被广泛使用和测试。如果稳定性高于一切,它可能是一个不错的选择,但你没有在列表中提到它,所以我假设它已经过时了。对于某些工作负载,这很糟糕——但任何通用 malloc 也是如此。
如果您愿意为此付费(而且价格合理,根据我的经验),SmartHeap SMP也是一个不错的选择。提到的大多数其他分配器都设计为可以 LD_PRELOAD 的插入式 malloc/free new/delete 替换。SmartHeap 也可以这样使用,但它还包括一个完整的与分配相关的 API,可让您根据自己的需要微调分配器。在我们已经完成的测试中(同样,非常特定于特定应用程序),SmartHeap 作为替代 malloc 时的性能与 Hoard 大致相同;两者的真正区别在于定制的程度。您需要分配器的通用性越低,您就可以获得更好的性能。
并且根据您的用例,通用多线程分配器可能根本不是您想要使用的;如果您不断地 malloc 和释放大小相同的对象,您可能只想编写一个简单的平板分配器。Slab 分配用于 Linux 内核中符合该描述的多个位置。(我会给你几个更有用的链接,但我是一个“新用户”,Stack Overflow 决定不允许新用户在一个答案中提供太多帮助。不过,谷歌可以提供足够的帮助。)
我个人更喜欢并推荐 ptmalloc 作为多线程分配器。Hoard 很好,但是在几年前我的团队在 Hoard 和 ptmalloc 之间进行的评估中,ptmalloc 更好。据我所知,ptmalloc 已经存在了很多年,并且被广泛用作多线程分配器。
您可能会发现此比较很有用。
也许这是处理您所要求的错误的方法,但也许可以完全采用不同的策略。如果您正在寻找一个非常快速的内存分配器,也许您应该问为什么您需要花费所有时间分配内存,而您也许可以摆脱变量的堆栈分配。堆栈分配虽然更烦人,但正确完成可以为您节省很多互斥争用的方式,以及避免代码中出现奇怪的内存损坏问题。此外,您可能会有更少的碎片,这可能会有所帮助。
我们在几年前我工作的一个项目中使用了hoard。它似乎工作得很好。我对其他分配器没有经验。尝试不同的并进行负载测试应该很容易,不是吗?
locklessinc 分配器非常好,如果您有问题,开发人员会及时响应。他写了一篇关于使用的一些优化技巧的文章,读起来很有趣:http: //locklessinc.com/articles/allocator_tricks/。我过去用过它,效果很好。
可能对您的问题的答复较晚,但是
如果你有性能提升,为什么要使用 mallocs?
更好的方法是在初始化时做一个大内存窗口的 malloc,然后想出light weight Memory manager
一个lease out the memory chunks at run time
。
如果您的堆扩展,这可以避免任何系统调用的可能性。
您可以尝试ltalloc(具有快速池分配器速度的通用全局内存分配器)。