0

我目前正在为 C++ 编写一个基于分配器概念的内存管理库。比较简单,目前所有的分配器都实现了这两个成员函数:

virtual void * alloc( std::size_t size ) = 0;
virtual void   dealloc( void * ptr ) = 0;

如您所见,我不支持界面中的对齐,但这实际上是我的下一步:) 以及我问这个问题的原因。

我希望分配器负责对齐,因为每个分配器都可以专门化。例如,块分配器只能返回块大小的对齐内存,因此它可以处理失败并在要求不同的对齐时返回 NULL。

我的一些分配器实际上是子分配器。例如,其中之一是线性/顺序分配器,它只是在分配时发生指针碰撞。这个分配器是通过传入一个 char * pBegin 和 char * pEnd 来构造的,它从内存中的那个区域内进行分配。现在,它工作得很好,但我得到了 1 字节对齐的东西。它适用于 x86,但我听说它在其他 CPU(控制台?)上可能是灾难性的。在 x86 上的读写速度也有点慢。

我知道实现对齐内存管理的唯一明智的方法是分配一个额外的 sizeof( void * ) + (alignement - 1) 字节并进行指针位掩码以返回对齐的地址,同时将原始分配的地址保留在之前的字节中用户数据(void * 字节,见上文)。

好吧,我的问题...

每次分配的开销对我来说似乎很大。对于 4 字节对齐,我将在 32 位 cpu 上有 7 个字节的开销,在 64 位 cpu 上有 11 个字节。这似乎很多。

首先,是不是很多?我是否与您过去可能使用过或正在使用的其他内存管理库相提并论?我研究了 malloc ,它似乎至少有 16 字节的开销,对吗?

您是否知道将对齐的内存返回给我的 lib 用户的更好方法,更小的开销?

4

2 回答 2

1

您可以存储一个偏移量,而不是一个指针,它只需要大到足以存储最大支持的对齐方式。如果您只支持较小的对齐方式,一个字节甚至可能就足够了。

于 2012-12-08T20:20:34.620 回答
0

您如何实现一个可以根据您的要求进行 x 字节对齐的伙伴系统。

大概的概念:

  1. 当你的库被初始化时,分配一大块内存。对于我们的示例,假设为 16B。(只有这个块需要对齐,算法不会要求你对齐任何其他块)
  2. 维护功率为 2 的内存块的列表。即 4B、8B、16B、... 64KB、... 1MB、2MB、... 512MB。
  3. 如果用户要求 8B 的数据,检查 8B 的列表,如果不可用,检查 16B 的列表并将其拆分为 2 个 8B 块。将一个还给用户,另一个将附加到 8B 列表中。
  4. 如果用户要求 16B,请检查您是否至少有 2 个 8B 可用。如果是,将它们组合起来并回馈给用户。如果没有,则系统没有足够的内存。

优点:

  1. 没有内部或外部碎片。
  2. 无需对齐。
  3. 快速访问内存块,因为它们是预先分配的。
  4. 如果列表是一个数组,直接访问不同大小的内存块

缺点:

  1. 内存列表的开销。
  2. 如果列表是链表,遍历会很慢。
于 2012-12-08T20:45:48.227 回答