4

我在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 new数据operator delete
    • cache_suballoc-cache_suballoc模板类将释放的内存块存储在一个长度无限的空闲列表中,使用,并在空闲列表为空时freelist<sizeof(Type), max_unbounded>从分配的更大块中重新分配内存块。operator new每个块都包含Sz * Nelts可用内存的字节数以及所需的operator new数据operator delete。分配的块永远不会被释放。
    • cache_chunklist- 此模板类用于operator new分配原始内存块,在需要时为内存块分配存储空间;它将释放的内存块存储在每个块的单独空闲列表中,并operator delete在其内存块均未使用时用于释放块。每个内存块都保存Sz着可用内存的字节数和一个指向它所属块的指针。每个块包含Nelts内存块、三个指针、一个 int 和所需的operator new数据operator delete

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

4

2 回答 2

7

哇,他们真的把文档弄乱了,不是吗?(我在 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 文档;我不知道 Microsoft 的东西将这些名称放在哪个名称空间中,但大概是宏将正确的名称放在那里)。

对于缓存模板:

  • cache_freelist维护一个节点大小的块的链表;列表的最大大小由模板参数设置Sz,节点分配由operator newand管理operator delete
  • cache_suballoc添加另一个管理节点块块的层Nelts,所有节点块都分配为单个 blob;新元素的分配首先查看空闲列表,如果没有空闲,则分配一个新的 blob。在分配器被销毁之前,不会删除内存块。
  • cache_chunklist以 blob 的形式分配内存(如cache_suballoc),但不使用公共空闲列表;当一个块被释放时,它会回到它的 blob 的空闲列表中。当所有 blob 块已被释放时,该 blob 本身将被删除。
于 2012-10-18T15:34:33.060 回答
0

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

一些宏使用动词“yields”,大致意思是“最终扩展为,可能通过多个步骤”。

缓存模板保存已释放的块以供以后重新分配。您将选择最适合您的分配模式的缓存,在重用百分比和缓存大小之间具有最佳折衷的缓存(请参阅上面的分析)。

一些缓存模板具有有限数量的释放块,通过freelist<>. Max 类决定了这样一个freelist可以变成多长时间。

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

于 2012-10-18T13:09:51.573 回答