【问题标题】:How do I use microsoft's C++ allocators如何使用微软的 C++ 分配器
【发布时间】:2012-10-08 03:54:40
【问题描述】:

我在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 参数中传递的类max class 确定。每个内存块包含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 需要的数据。

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

【问题讨论】:

  • this 有帮助吗?例如,他们提到了 ALLOCATOR_DECL,并解释了为什么以及如何使用它。
  • 我使用该页面生成问题。重读它确实解释了如何使用该宏,但没有解释其他类型。此外,解释如何使用宏的部分有误导我的错别字。他们混合了Allocalloc<int>
  • 您是从这个页面开始的吗:msdn.microsoft.com/en-us/library/ee292134.aspx。很清楚如何使用这个分配器和宏。您的链接(从本页链接)只是普通用户不需要理解的技术细节。也许标题本身会更容易理解。您是否尝试阅读标题?
  • 尚未阅读 cmets/header,没有。
  • @PiotrNycz:阅读该页面。我仍然没有得到缓存或宏,因此,底部的分配器。

标签: c++ stl allocator


【解决方案1】:

哇,他们真的把文档弄乱了,不是吗? (我在 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 newoperator delete 管理。
  • cache_suballoc 添加了另一个层来管理 Nelts 节点块的块,所有这些都作为单个 blob 分配;新元素的分配首先查看空闲列表,如果没有空闲,则分配一个新的 blob。在分配器被销毁之前,不会删除内存块。
  • cache_chunklist 以 blob 形式分配内存(如 cache_suballoc),但不使用公共空闲列表;当一个块被释放时,它会回到它的 blob 的空闲列表中。当所有 blob 块都被释放后,该 blob 本身将被删除。

【讨论】:

  • 显然我的问题措辞不佳,我正在寻找什么,所以我重写了它。具体来说,每个缓存模板是什么?
  • @MooingDuck - 感谢您的编辑。我没有想清楚。一边参加 C++ 标准委员会会议一边写作。
  • 很荣幸您回答了我的问题! :D
【解决方案2】:

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

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

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

一些缓存模板具有有限数量的释放块,通过freelist&lt;&gt; 实现。 Max 类决定了这种freelist 可以变成多长时间。

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

【讨论】:

  • 那么cache_freelistcache_suballoccache_chunklist有什么区别?
猜你喜欢
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 2017-05-06
  • 1970-01-01
相关资源
最近更新 更多