内存池的初始块大小

时间:2015-12-16 20:33:50

标签: c++ memory-pool

我正在使用C ++模板实现一个内存池类,我想知道块的大小是多少。例如:

template <typename T>
class Mempool {

  unsigned char* block;

  // constructor. 
  Mempool() {
    block = malloc(sizeof(T)*DEFAULT_N)
  }

};

在上面的示例中,块大小实际上取决于类型T以及要创建的元素数量的默认值。这样做的最佳(或常见)练习是什么?我应该考虑块大小的内存对齐吗?

1 个答案:

答案 0 :(得分:0)

我只能提供一些一般性建议,因为很多将取决于实际用例:

<强>对齐: 我想池应确保其中的对象正确对齐。这意味着您可能希望将对象放置在至少是std::alignment_of<T>::valuealignof(T)的倍数的内存位置。

缓存友好性:池还可以将对象位置四舍五入到缓存行大小的倍数,因此(小)对象永远不会放在两个缓存行中但始终位于一个人。

填充:如果对象非常小(只有几个字节),但你有很多,那么任何额外的填充可能会增加内存需求,这取决于应用程序是否会是一个问题。当对象没有保持在靠近的位置并且存在大量缓存未命中时,过多的填充实际上可能会损害性能。

基础内存管理:最后,良好的块大小也可能取决于底层存储。您可能希望分配大小与OS页面大小匹配,或使用它们的倍数。此外,如果malloc很昂贵,那么您可能希望尽可能少地调用它以避免系统调用开销和争用。在malloc更便宜的环境中,可以更频繁地使用较小的初始块大小和malloc,但malloc仍会有一些开销。其中很多是特定于操作系统的。

因此,无论您选择哪种初始大小,都应该针对某些典型工作负载测量内存使用情况和分配性能。这将允许您进行比纯粹猜测所能提供的更有根据的估计。

最后,有一些现成的malloc替换,例如 tcmalloc jemalloc ,它们的特征可能与您的操作系统{{{ 1}}。因此,一个很好的选择是检查其中一个,而不是滚动自己的分配器。