【问题标题】:Can the global new operator be overridden based on allocated object's type traits?可以根据分配对象的类型特征覆盖全局 new 运算符吗?
【发布时间】:2013-05-24 23:29:32
【问题描述】:

我正在尝试升级我们的池化固定块内存分配器以利用 C++11 类型特征。

目前可以通过以传统方式覆盖the global new operator 来强制将任何对象的任何分配分配到正确的池中,例如

void* operator new (std::size_t size) 
{ // if-cascade just for simplest possible example
   if ( size <= 64 ) { return g_BlockPool64.Allocate(); }
   else if ( size <= 256 ) { return g_BlockPool256.Allocate(); }
   // etc .. else assume arguendo that we know the following will work properly
   else return malloc(size);
}

在许多情况下,如果可以根据类型特征(例如 is_trivially_destructible)将对象分派到不同的池中,我们可以进一步提高性能。 是否可以创建一个模板化的全局 new 运算符,它知道分配的类型,而不仅仅是请求的大小? 相当于

template<class T>
void *operator new( size_t size)
{
  if ( size < 64 ) 
  {  return std::is_trivially_destructible<T>::value ? 
            g_BlockPool64_A.Allocate() : 
            g_BlockPool64_B.Allocate(); } //  etc
}

在每个类中重写成员 new 运算符在这里不起作用;我们真的需要它来自动为任何地方的任何分配工作。放置 new 也不起作用:要求每个 alloc 看起来像

Foo *p = new (mempool<Foo>) Foo();

太麻烦了,人家会忘记用的。

【问题讨论】:

  • 好主意。虽然可以简单地破坏如何帮助内存管理器?经理不在乎建造或破坏。
  • @GManNickG 如果所有可简单破坏的对象都进入同一个池,我们可以通过取消映射内存页面而不调用任何析构函数来整体释放它们。这是一个操作系统调用,而不是数百万次释放。当一个关卡块的所有分配都进入一个块并且您可以在离开该区域时将其扔到海里时很有用。已经有其他机制可以防止人们在其生命周期内持有指向该块的指针。
  • 没有。另外,return ::new(size); 是无限递归。
  • 当然,但这与生命周期策略有关,而不是内存分配。您不能只是决定随时释放内存块,您必须等待该内存中的对象的生命周期结束,无论这种破坏多么微不足道。要做到这一点,您必须在应用程序代码中的一个点做​​出决定,“好的,这整个块可以消失(并且驻留在那里的对象的生命周期将被隐式结束)”。我不知道内存管理器如何决定一些可简单破坏的对象是否属于一组或另一组,所以这段代码必须驻留在它之外。
  • 不管怎样,通常的做法是编写一个arena_allocator,在应用层明确使用它来将分配组合在一起。

标签: c++ c++11 typetraits


【解决方案1】:

简短的回答是否定的。分配/解除分配函数具有以下签名:

void* operator new(std::size_t);
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);

与这些签名的大多数偏差将导致您的函数根本不被使用。在典型的实现中,您基本上是在链接器级别替换默认实现 - 即,现有函数具有一些特定的错位名称。如果您提供的函数名称与相同的结果不一致,则它将被链接。如果您的函数没有重命名为相同的名称,则它不会被链接。

在某些情况下可能会使用您建议的模板,但如果是这样,则会导致未定义的行为。根据您安排标题的方式(例如),您最终可能会将模板的使用与默认函数混合使用的代码,此时您所希望的最好的结果就是它快速而干净地崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多