这个问题的一些背景可能会有所帮助:我有用C ++编写的多线程应用程序,其中内存管理是性能方面的关键点。我已经实现了'main'分配器,让我们假设它被称为'ManagedAllocator'。我还有自己的多平台线程本地存储支持,使用asm
CPU寄存器在fs
中编写。所以基本上,现在我的全局运算符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那样进行操作,因为我需要在TLS数组中使用一个插槽用于 FixedPoolAllocator的每个特化。
但是,我不想玩锁,因为整个过程就是拥有无锁分配。有没有办法以干净,优雅的方式做到这一点?*更新*
我忘了提一件事:我真正需要做的事。
我有简单的课程:
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。