可遍历内存池的数据结构

时间:2014-04-28 15:45:19

标签: c++ memory memory-management data-structures

我在C ++中实现了一个内存池,具有以下约束:

  • 分配的元素应按行内容的顺序以线性时间遍历,以促进缓存重用。
  • 需要释放元素(内存块)并将它们返回到内存池。

在实时程序的运行期间经常会发生分配和释放,因此需要尽快发生。

到目前为止,我已使用两个链接列表作为存根来实现此内存池,一个用于free,另一个用于已分配的元素。这是有效的,但当然非常慢,因为每次释放或分配元素时,元素都需要从一个列表中删除并添加到另一个列表中,这是线性的。我希望这更快。

我可以使用哪些数据结构尽可能高效地进行(de)分配?我正在考虑使用红黑树(或类似的平衡BST)来存储分配的元素,以及free元素的优先级队列。这将使分配和释放都为O(log n)。

关于如何改进此设计的任何建议?我可以使用其他数据结构?是否可以使用常量时间操作来创建内存池(具有上述约束)?

编辑:我应该澄清一下,这些数据结构仅用于存储和访问内存地址,内存块本身已经分配并且是连续的。

1 个答案:

答案 0 :(得分:1)

由于我们正在处理具有固定大小的内存块的内存池,因此可以按如下方式实现恒定时间操作。 :

  • 通过其对池的索引来识别每个内存块(内存块的地址可以通过block_address = base_address + index * block_size轻松地从该索引派生,反之亦然。)
  • 具有元数据的数据结构(用于跟踪已分配和空闲的块)。符合要求的是固定大小的数组,其中的项目对应于每个内存块(由相同的索引标识)。嵌入在该数组中的是两个(双重)链表(一个用于分配,一个用于空闲块)。由于这些链接列表不重叠,因此它们可以使用相同的prevnext指针。

这如何符合要求:

  • 线性时间遍历:内存块可以通过它们的索引遍历(作为元数据的一部分的空闲/分配标志在这种情况下可能是有用的),或者通过两者中的任何一个链接列表,取决于要求。迭代数组和链表是在线性时间内完成的。
  • 常量时间分配:分配内存块意味着从空闲列表中获取第一个项目,并将其移动到已分配的列表中(例如,最终)。删除链接列表的第一项,并将项目附加到链接列表的末尾都是常量时间操作(假设指向链接列表的开头和/或结尾的指针 - 使列表循环可以帮助) 。然后返回块的索引/地址。
  • 常量时间释放:解除分配内存块意味着通过索引识别相应的元数据项,并将其从分配的列表移动到空闲列表中(例如,最后)。通过索引从数组中获取项目,从(双重)链接列表中删除给定项目,并将项目附加到链接列表的末尾,都是常量时间操作。