Optimization: custom pools are on an intrusive double linked list not sorted vector
Added struct PoolListItemTraits.
diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp
index 02c6fa6..f641c96 100644
--- a/src/D3D12MemAlloc.cpp
+++ b/src/D3D12MemAlloc.cpp
@@ -477,14 +477,6 @@
return end;
}
-struct PointerLess
-{
- bool operator()(const void* lhs, const void* rhs) const
- {
- return lhs < rhs;
- }
-};
-
static UINT HeapTypeToIndex(D3D12_HEAP_TYPE type)
{
switch(type)
@@ -2714,6 +2706,47 @@
}
};
+class PoolPimpl
+{
+public:
+ PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc);
+ HRESULT Init();
+ ~PoolPimpl();
+
+ AllocatorPimpl* GetAllocator() const { return m_Allocator; }
+ const POOL_DESC& GetDesc() const { return m_Desc; }
+ BlockVector* GetBlockVector() { return m_BlockVector; }
+
+ HRESULT SetMinBytes(UINT64 minBytes) { return m_BlockVector->SetMinBytes(minBytes); }
+
+ void CalculateStats(StatInfo& outStats);
+
+ void SetName(LPCWSTR Name);
+ LPCWSTR GetName() const { return m_Name; }
+
+private:
+ friend class Allocator;
+ friend struct PoolListItemTraits;
+
+ AllocatorPimpl* m_Allocator; // Externally owned object.
+ POOL_DESC m_Desc;
+ BlockVector* m_BlockVector; // Owned object.
+ wchar_t* m_Name;
+ PoolPimpl* m_PrevPool = NULL;
+ PoolPimpl* m_NextPool = NULL;
+
+ void FreeName();
+};
+
+struct PoolListItemTraits
+{
+ typedef PoolPimpl ItemType;
+ static ItemType* GetPrev(const ItemType* item) { return item->m_PrevPool; }
+ static ItemType* GetNext(const ItemType* item) { return item->m_NextPool; }
+ static ItemType*& AccessPrev(ItemType* item) { return item->m_PrevPool; }
+ static ItemType*& AccessNext(ItemType* item) { return item->m_NextPool; }
+};
+
class AllocatorPimpl
{
public:
@@ -2856,8 +2889,8 @@
CommittedAllocationList m_CommittedAllocations[HEAP_TYPE_COUNT];
D3D12MA_RW_MUTEX m_CommittedAllocationsMutex[HEAP_TYPE_COUNT];
- typedef Vector<Pool*> PoolVectorType;
- PoolVectorType* m_pPools[HEAP_TYPE_COUNT];
+ typedef IntrusiveLinkedList<PoolListItemTraits> PoolList;
+ PoolList m_Pools[HEAP_TYPE_COUNT];
D3D12MA_RW_MUTEX m_PoolsMutex[HEAP_TYPE_COUNT];
// Default pools.
@@ -2957,9 +2990,9 @@
// Unregisters Allocation object from m_CommittedAllocations.
void UnregisterCommittedAllocation(Allocation* alloc, D3D12_HEAP_TYPE heapType);
- // Registers Pool object in m_pPools.
+ // Registers Pool object in m_Pools.
void RegisterPool(Pool* pool, D3D12_HEAP_TYPE heapType);
- // Unregisters Pool object from m_pPools.
+ // Unregisters Pool object from m_Pools.
void UnregisterPool(Pool* pool, D3D12_HEAP_TYPE heapType);
HRESULT UpdateD3D12Budget();
@@ -4312,35 +4345,6 @@
////////////////////////////////////////////////////////////////////////////////
// Private class PoolPimpl
-class PoolPimpl
-{
-public:
- PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc);
- HRESULT Init();
- ~PoolPimpl();
-
- AllocatorPimpl* GetAllocator() const { return m_Allocator; }
- const POOL_DESC& GetDesc() const { return m_Desc; }
- BlockVector* GetBlockVector() { return m_BlockVector; }
-
- HRESULT SetMinBytes(UINT64 minBytes) { return m_BlockVector->SetMinBytes(minBytes); }
-
- void CalculateStats(StatInfo& outStats);
-
- void SetName(LPCWSTR Name);
- LPCWSTR GetName() const { return m_Name; }
-
-private:
- friend class Allocator;
-
- AllocatorPimpl* m_Allocator; // Externally owned object.
- POOL_DESC m_Desc;
- BlockVector* m_BlockVector; // Owned object.
- wchar_t* m_Name;
-
- void FreeName();
-};
-
PoolPimpl::PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc) :
m_Allocator(allocator),
m_Desc(desc),
@@ -4368,6 +4372,7 @@
PoolPimpl::~PoolPimpl()
{
+ D3D12MA_ASSERT(m_PrevPool == NULL && m_NextPool == NULL);
FreeName();
D3D12MA_DELETE(m_Allocator->GetAllocs(), m_BlockVector);
}
@@ -4477,7 +4482,6 @@
// desc.pAllocationCallbacks intentionally ignored here, preprocessed by CreateAllocator.
ZeroMemory(&m_D3D12Options, sizeof(m_D3D12Options));
- ZeroMemory(m_pPools, sizeof(m_pPools));
ZeroMemory(m_BlockVectors, sizeof(m_BlockVectors));
ZeroMemory(m_DefaultPoolTier1MinBytes, sizeof(m_DefaultPoolTier1MinBytes));
@@ -4486,11 +4490,6 @@
m_DefaultPoolHeapTypeMinBytes[i] = UINT64_MAX;
}
- for(UINT heapTypeIndex = 0; heapTypeIndex < HEAP_TYPE_COUNT; ++heapTypeIndex)
- {
- m_pPools[heapTypeIndex] = D3D12MA_NEW(GetAllocs(), PoolVectorType)(GetAllocs());
- }
-
m_Device->AddRef();
m_Adapter->AddRef();
}
@@ -4573,12 +4572,10 @@
for(UINT i = HEAP_TYPE_COUNT; i--; )
{
- if(m_pPools[i] && !m_pPools[i]->empty())
+ if(!m_Pools[i].IsEmpty())
{
D3D12MA_ASSERT(0 && "Unfreed pools found!");
}
-
- D3D12MA_DELETE(GetAllocs(), m_pPools[i]);
}
for(UINT i = HEAP_TYPE_COUNT; i--; )
@@ -5565,9 +5562,7 @@
const UINT heapTypeIndex = HeapTypeToIndex(heapType);
MutexLockWrite lock(m_PoolsMutex[heapTypeIndex], m_UseMutex);
- PoolVectorType* const pools = m_pPools[heapTypeIndex];
- D3D12MA_ASSERT(pools);
- pools->InsertSorted(pool, PointerLess());
+ m_Pools[heapTypeIndex].PushBack(pool->m_Pimpl);
}
void AllocatorPimpl::UnregisterPool(Pool* pool, D3D12_HEAP_TYPE heapType)
@@ -5575,10 +5570,7 @@
const UINT heapTypeIndex = HeapTypeToIndex(heapType);
MutexLockWrite lock(m_PoolsMutex[heapTypeIndex], m_UseMutex);
- PoolVectorType* const pools = m_pPools[heapTypeIndex];
- D3D12MA_ASSERT(pools);
- bool success = pools->RemoveSorted(pool, PointerLess());
- D3D12MA_ASSERT(success);
+ m_Pools[heapTypeIndex].Remove(pool->m_Pimpl);
}
void AllocatorPimpl::FreeCommittedMemory(Allocation* allocation)
@@ -5668,12 +5660,10 @@
for(size_t heapTypeIndex = 0; heapTypeIndex < HEAP_TYPE_COUNT; ++heapTypeIndex)
{
MutexLockRead lock(m_PoolsMutex[heapTypeIndex], m_UseMutex);
- const PoolVectorType* const poolVector = m_pPools[heapTypeIndex];
- D3D12MA_ASSERT(poolVector);
- for(size_t poolIndex = 0, count = poolVector->size(); poolIndex < count; ++poolIndex)
+ PoolList& poolList = m_Pools[heapTypeIndex];
+ for(PoolPimpl* pool = poolList.Front(); pool != NULL; pool = poolList.GetNext(pool))
{
- Pool* pool = (*poolVector)[poolIndex];
- pool->m_Pimpl->GetBlockVector()->AddStats(outStats);
+ pool->GetBlockVector()->AddStats(outStats);
}
}