0

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

template <typename T>
class Mempool {

  unsigned char* block;

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

};

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

4

1 回答 1

0

我只能给出一些一般性建议,因为很大程度上取决于实际用例:

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

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

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

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

因此,无论您选择什么初始大小,您都应该测量一些典型工作负载的内存使用情况和分配性能。这将使您做出比纯粹猜测所能提供的更有根据的估计。

最后,还有现成的 malloc 替代品,例如tcmallocjemalloc,它们可能具有与您的操作系统完全不同的特性malloc。因此,一个不错的选择是检查其中一个,而不是滚动您自己的分配器。

于 2015-12-17T20:36:12.473 回答