[英]How do I use microsoft's C++ allocators
我在http://msdn.microsoft.com/en-us/library/ee292117.aspx和http://msdn.microsoft.com/en-us/library/ee292134.aspx上看到Microsoft为专门提供的宏和类分配器,但我不确定每个缓存策略是什么,如何使用它们。 有人可以解释何时使用这些部件?
cache_freelist
- cache_freelist
模板类维护一个大小为Sz
的内存块的空闲列表。 当空闲列表已满时,它使用operator delete
来释放内存块。 当空闲列表为空时,它使用operator new
来分配新的内存块。 空闲列表的最大大小由Max
参数中传递的类max class
确定。 每个存储器块保存Sz
字节的可用存储器以及operator new
和operator delete
所需的数据。 cache_suballoc
- cache_suballoc
模板类将释放的内存块存储在具有无限长度的空闲列表中,使用freelist<sizeof(Type), max_unbounded>
,并在空闲列表为空时从使用operator new
分配的较大块freelist<sizeof(Type), max_unbounded>
分配内存块。 每个块保存可用内存的Sz * Nelts
字节以及operator new
和operator delete
所需的数据。 从未释放分配的块。 cache_chunklist
- 此模板类使用operator new
来分配原始内存块,子分配块以在需要时为内存块分配存储空间; 它将释放的内存块存储在每个块的单独空闲列表中,并使用operator delete
在没有任何内存块正在使用时释放块。 每个内存块保存Sz
字节的可用内存和指向它所属的块的指针。 每个块都包含Nelts
内存块,三个指针,一个int以及operator new
和operator delete
所需的数据。 我自己写了几个分配器,但是这个文档只是......令人困惑。
哇,他们真的乱了文档,不是吗? (当我在Dinkumware时,我写了那段代码)
这里的分配器是基于策略的:您可以指定缓存策略和同步策略。
基本思想是使编写使用内部缓存的分配器更容易,并且可以跨线程同步。 有六个预定义的分配器; 他们的名字都以allocator_
开头。 如果符合您的需要,请使用它们。 在MSDN中,查看特定分配器描述的第一段; 不要阅读“备注”,他们在那里谈论ALLOCATOR_DECL
;
您还可以使用该代码创建自己的分配器,这些分配器使用预定义的缓存策略(名称以cache_
开头的模板)和同步策略(名称以sync_
开头的模板),或者使用您自己的缓存模板和同步模板。 从这些部分获取可用的分配器有点单调乏味,因此标题提供了ALLOCATOR_DECL
作为生成所有必需样板的便捷方式,而无需自己编写。 ALLOCATOR_DECL
有三个参数:要使用的缓存模板的名称,要使用的同步模板的名称以及您正在创建的分配器的名称。 所以不要写作
template <class T> class name
: public Dinkum::allocators::allocator_base<T, sync<cache > >
{
public:
name() {}
template <class U> name(const name<U>&) {}
template <class U> name& operator = (const name<U>&)
{return *this; }
template <class U> struct rebind
{ /* convert a name<T> to a name<U> */
typedef name<U> other;
};
};
你会写ALLOCATOR_DECL(cache, sync, name);
。 allocator_base
完成了繁重的工作; 分配器本身必须是派生类型,以便它可以正确处理rebind
。 (该代码中的Dinkum
来自Dinkumware文档;我不知道微软的东西将这些名称放在哪个命名空间中,但可能是宏在那里放了正确的名称)。
对于缓存模板:
cache_freelist
维护节点大小的块的链表; 列表的最大大小由模板参数Sz
,节点分配由operator new
和operator delete
。 cache_suballoc
添加另一个层来管理一个Nelts
节点块,所有这些层都被分配为一个blob; 新元素的分配首先查看空闲列表,如果没有空闲,则分配新的blob。 在销毁分配器之前,不会删除内存块。 cache_chunklist
在blob中分配内存(如cache_suballoc
),但不使用公共空闲列表; 当一个块被释放时,它会回到它的blob的空闲列表中。 释放所有blob块后,将删除blob本身。 第一个问题很简单。 什么时候使用它们? 分析显示默认分配器的问题。 仅这一点就使问题与大多数开发人员无关。
一些宏使用动词“yield”,松散意味着“最终扩展到,可能通过多个步骤”。
缓存模板保存解除分配的块以供以后重新分配。 您将选择最适合您的分配模式的缓存,即在重用%和缓存大小之间具有最佳权衡的缓存(请参阅上面的分析)。
一些缓存模板具有有限数量的释放块,通过freelist<>
。 Max类确定这样的freelist
可以变成多长时间。
分配器最终是预先组合的上述组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.