阅读 Apache模块书,我在第3.4.3部分中遇到了这个主张:
“第二个好处是在大多数平台上池分配比malloc更快!”
一个悬而未决的问题,我意识到,但是......好吧,为什么?
答案 0 :(得分:5)
除了Lars关于地点的观点之外,游泳池分配只是与malloc
不同的速度/灵活性权衡。
malloc
必须跟踪每个已分配的块,能够单独释放块,处理空闲块碎片和合并,有一些策略可以选择分配哪些空闲块等等。
这是通用分配器的必需,但是通过让调用者决定其中一些,池可以避免所有这些复杂性(以及相关的空间和运行时开销)行为静态。
Apache示例似乎只允许整个池重新分配(因此它就像arena allocator)。这意味着它不需要跟踪单个分配记录,它们的生命周期以及零碎的免费商店。它只需要跟踪一个(或多个)大块内存,并更新指向下一个未使用空间的指针。请注意,即使使用malloc
分配这些大块,此成本通常会通过许多池分配进行摊销。
其他池类型可能仅限于相同大小(或类型)的对象,这进一步简化了它们;他们甚至可以保持LIFO免费清单接近零成本,允许每记录重新分配。
答案 1 :(得分:3)
池分配策略可以带来更好的性能 有两种方式。 在数据结构遍历的应用程序中 匹配数据分配顺序,汇集策略可以 暴露更多的常规步伐。
例如,考虑搜索 通过链接的记录列表。每条记录由一个 键字段,数据字段和指向该字段的下一个字段 列表中的下一条记录。访问键和下一个字段 连续,直到找到匹配。只有到那时 访问数据字段。 如果数据存储在每个中 记录本身就是一个堆对象,更糟糕的是,数据在变化 大小形式记录到下一个,有各种不良影响 关于工作集的空间局部性。即数据 不必要地从内存中取出,消耗宝贵的东西 带宽。
此外,由于可变长度数据介于其间 关键字段和下一个字段,记录中的步幅, 并且连续记录将出现不规则。就这样 不同对象类型的隔离可以改善空间局部性, 同时,整体表现。
此外, 因为池分配可能会暴露更多的常规步幅,a 简单的预取策略可以预测未来的参考 并缩短他们的内存访问延迟。