65.9K
CodeProject 正在变化。 阅读更多。
Home

用于加速 VC++ STL 的自定义块分配器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.63/5 (19投票s)

2000 年 5 月 11 日

CPOL
viewsIcon

247876

downloadIcon

1535

一个块分配器,可与 STL 容器配合使用,显著提高了执行大量数据插入和提取操作的程序的运行速度。

引言

block_allocator 是一个自定义 STL 分配器,可与 Microsoft VC++ 中实现的 STL 配合使用。block_allocator 不会按节点进行分配,而是以固定大小的块分配内存,并按请求提供这些块的一部分。与默认分配器相比,速度通常提高了 40%。块的大小由用户设置,不应太小(会降低速度提升)也不应太大(会浪费内存)。进行实验,找出最适合您应用程序的大小。

block_allocator 可以替换以下容器中的默认分配器

  • 列表,
  • set,
  • multiset,
  • map,
  • multimap,
但不能用于 `vector` 或 `queue` 等其他容器。请注意,`vector` 和 `queue` 本身已经会进行分块分配。使用 `block_allocator` 非常简单,例如:
// block allocated list of ints with chunks of 1024 elements
std::list<int,block_allocator<int,1024> > l;
常规容器和块分配的容器可以共存而不会出现问题。

与 MSVC++ 6.0/7.0 的兼容模式

由于这些编译器附带的标准库存在限制,因此上述使用模式在此处不适用。要解决此问题,必须按以下步骤操作:对于每个支持的容器,都有一个关联的块分配容器,该容器是通过使用 `block_allocator` 从其派生出来的。您必须为每个要定义的容器定义一个激活宏,然后才能包含 *blockallocator.h*

  • list -> block_allocated_list (宏 DEFINE_BLOCK_ALLOCATED_LIST),
  • set -> block_allocated_set (宏 DEFINE_BLOCK_ALLOCATED_SET),
  • multiset -> block_allocated_multiset (宏 DEFINE_BLOCK_ALLOCATED_MULTISET),
  • map -> block_allocated_map (宏 DEFINE_BLOCK_ALLOCATED_MAP),
  • multimap -> block_allocated_multimap (宏 DEFINE_BLOCK_ALLOCATED_MULTIMAP),

要在您的应用程序中使用基于块分配的 STL,请定义相应的激活宏,包含 *blockallocator.h*,然后像这样更改您的声明:

  • list<type> -> block_allocated_list<type,chunk_size>
  • set<key> -> block_allocated_set<key,chunk_size>
  • multiset<key> -> block_allocated_multiset<key,chunk_size>
  • map<key,type> -> block_allocated_map<key,type,chunk_size>
  • multimap<key,type> -> block_allocated_multimap<key,type,chunk_size>

其中 `chunk_size` 是块的大小。您也可以输入其他可选的模板参数(有关更多信息,请参阅 MSVC++ STL 文档)。

MSVC++ 6.0/7.0 兼容模式也可在 MSVC++ 7.1 中使用,因此在将旧代码移植到 7.1 时,您无需修改 `block_allocator` 相关的代码。

多线程问题

每个块分配的容器实例都使用自己的 `block_allocator`,因此只要您的程序方便地保护其容器免受并发访问(或者没有两个线程访问同一个容器实例),就不会出现多线程问题。这与常规 STL 类的情况相同(请记住,容器上的操作不受 `CRITICAL_SECTION` 或类似机制的保护),因此,关键在于:如果您的程序在没有 `block_allocator` 的情况下是多线程安全的,那么使用它之后也会继续保持安全。

版本历史

  • 2000 年 2 月 29 日 - 1.1
    • 在 CodeProject 上首次发布。
  • 2001 年 3 月 22 日 - 1.2
    • 包含 `operator==` 和 `operator!=` 的定义。缺少这些定义会在调用 `list::swap()` 和类似方法时导致链接错误。有趣的是,没有人报告过这个看似重要的问题,要么是 `swap()` 使用频率不高,要么是很少有人使用 `block_allocator`!
  • 2006 年 10 月 25 日 - 1.3
    • 现在 `block_allocator` 可与 MSVC++ 7.1 和 8.0 配合使用。感谢 James May 协助测试此新版本代码。
  • 2006 年 10 月 30 日 - 1.4
    • 修复了 `block_allocated_list`、`block_allocated_set` 等中一些错误地设置为 `private` 的 `typedef`。
© . All rights reserved.