分配器库中每个分配开销较小

时间:2012-12-08 20:03:14

标签: c++ memory-management

我目前正在为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用户吗?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

一般理念:

  1. 初始化lib时,分配一大块内存。对于我们的例子,假设16B。 (只需要对齐此块,算法不需要您对齐任何其他块)
  2. 维护电源2的内存块列表。即4B,8B,16B,... 64KB,... 1MB,2MB,... 512MB。
  3. 如果用户要求提供8B数据,请检查8B列表(如果不可用),检查16B列表并将其拆分为2个8B块。将一个返回给用户,另一个返回到8B列表。
  4. 如果用户要求16B,请检查您是否有至少2 8B可用。如果是,请将它们组合并返回给用户。如果没有,系统没有足够的内存。
  5. 优点:

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

      1. 内存列表的开销。
      2. 如果列表是链表,则遍历会很慢。