4

这个问题的一些背景可能会有所帮助:我有用 C++ 编写的多线程应用程序,其中内存管理在性能方面是关键点。我已经实现了“主”分配器,假设它被称为“ManagedAllocator”。我也有自己的多平台线程本地存储支持,asm使用fsCPU 寄存器编写。所以基本上,现在我的全局运算符 new 看起来像这样:

void* operator new(Size_t memSize)
{
  Thread_data& tls = get_thread_local_data();
  ManagedAllocator* allocator = tls[TLS_INDEX_MANAGED_ALLOCATOR];
  return allocator->AllocateMemory(memSize);
}

分配器的本地实例的创建和销毁由每个线程执行。与标准分配器(已经在 Win7/8、Linux、MacOS 和 WP8 上测试过(TLS 的实现略有不同)相比,它的工作原理非常好且超快)。

现在,问题:我有以下课程:

template < Size_t Alloc_size >
class FixedPoolAllocator
{
};

ManagedAllocator 在内部使用了这个类,但最近发现我还需要将它用作独立的分配器。但是,我不能以与 ManagedAllocator 相同的方式执行此操作,因为我需要为FixedPoolAllocator的每个特化使用 TLS 数组中的一个插槽。

然而,我不想玩锁,因为整个事情就是要进行无锁分配。有没有办法以一种干净、优雅的方式做到这一点?


* 更新 *


我忘了提一件事:我真正需要做什么。

我有简单的课程:

template < class Allocator >
class EXS_INTERFACE CustomAllocObject
{
public:
  explicit CustomAllocObject();
  ~CustomAllocObject();

  static void* operator new(Size_t memSize);
  //also new[], placement versions, etc.

  static void operator delete(void* memPtr);
  //same as above
};

这只是:

template < class Allocator >
_EXSTemplateDef void*
CustomAllocObject<Allocator>::operator new(Size_t memSize)
{
  return Allocator::AllocateMemory(memSize);
}

我用它来创建需要快速分配的对象:

class Image : public CustomAllocObject< FixedSizeAllocator<sizeof(ImageInternal)> >
{
};

AllocateMemory() 是每个分配器类中的静态函数。所以完美的解决方案是:

template < Size_t Alloc_size >
_EXSTemplateDef void*
FixedPoolAllocator<Alloc_size>::AllocateMemory(Size_t memSize)
{
  FixedPoolAllocator<Alloc_size>* alloc = get_somehow_this_threads_instance();
  return alloc->PerformAllocation();
}

问题是,我不能这样做:

template < Size_t Alloc_size >
class FixedPoolAllocator
{
  //....
  static EXS_THREAD_LOCAL FixedPoolAllocator<Alloc_size> _local_instance;
};

因为库被编译为 DLL。FixedPoolAllocator 在这种情况下是 DLL_EXPORT 类(这意味着它的所有静态成员也是)并且不允许使用 DLL_EXPORTed THREAD_LOCAL。

4

0 回答 0