我如何使用microsoft的C ++分配器

时间:2012-10-17 19:34:04

标签: c++ stl allocator

我在http://msdn.microsoft.com/en-us/library/ee292117.aspxhttp://msdn.microsoft.com/en-us/library/ee292134.aspx上看到Microsoft为专门的分配器提供了宏和类,但我不确定每种缓存策略是什么,如何使用它们。有人可以解释何时使用这些部件?

  • 缓存模板
    • cache_freelist - cache_freelist模板类维护一个大小为Sz的内存块的空闲列表。当空闲列表已满时,它使用operator delete来释放内存块。当空闲列表为空时,它使用operator new来分配新的内存块。空闲列表的最大大小由max class参数中传递的类Max确定。每个内存块包含Sz字节的可用内存以及operator newoperator delete所需的数据。
    • cache_suballoc - cache_suballoc模板类使用freelist<sizeof(Type), max_unbounded>将解除分配的内存块存储在具有无限长度的空闲列表中,并从分配有operator new的较大块中子分配内存块当空闲列表为空时。每个块包含Sz * Nelts字节的可用内存以及operator newoperator delete所需的数据。从未释放分配的块。
    • cache_chunklist - 此模板类使用operator new分配原始内存块,子分配块以在需要时为内存块分配存储空间;它将释放的内存块存储在每个块的单独空闲列表中,并在没有使用任何内存块时使用operator delete解除分配块。每个内存块保存Sz字节的可用内存和指向它所属的块的指针。每个块包含Nelts个内存块,三个指针,一个int以及operator newoperator delete所需的数据。

我自己写了几个分配器,但这个文档只是......令人困惑。

2 个答案:

答案 0 :(得分:7)

哇,他们真的把文档弄乱了,不是吗? (当我在Dinkumware时,我写了那段代码)

此处的分配器是基于策略的:您可以指定缓存策略和同步策略。

基本思想是更容易编写使用内部缓存的分配器,并且可以跨线程同步。有六个预定义的分配器;他们的名字都以allocator_开头。如果符合您的需要,请使用它们。在MSDN中,查看特定分配器描述的第一段;不要阅读&#34;备注&#34;,他们在那里谈论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 newoperator delete管理。
  • cache_suballoc添加另一个层,用于管理Nelts个节点块的块,全部分配为单个blob;新元素的分配首先查看空闲列表,如果没有空闲,则分配新的blob。在销毁分配器之前,不会删除内存块。
  • cache_chunklist在blob中分配内存(如cache_suballoc),但不使用公共空闲列表;当一个块被释放时,它会回到它的blob的空闲列表中。当释放所有blob块时,blob本身将被删除。

答案 1 :(得分:0)

第一个问题很简单。什么时候使用它们?分析显示默认分配器的问题。仅这一点就使得这个问题与大多数开发人员无关。

一些宏使用动词“yield”,松散意味着“最终扩展到,可能通过多个步骤”。

缓存模板保存已释放的块以供以后重新分配。您将选择最适合您的分配模式的缓存,即在重用%和缓存大小之间进行最佳权衡的缓存(请参阅上面的分析)。

某些缓存模板具有有限数量的已释放块,通过freelist<>实现。 Max类确定freelist可以变为多久。

分配器最终是预先组合的上述组合。