mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-11-27 00:44:35 +00:00
Optimized VmaBlockMetadata_Linear::FreeAtOffset to use binary search.
Refactored VmaBinaryFindFirstNotLess.
This commit is contained in:
parent
bc7fea61d2
commit
0270b98d2f
@ -3003,8 +3003,8 @@ Cmp should return true if first argument is less than second argument.
|
|||||||
Returned value is the found element, if present in the collection or place where
|
Returned value is the found element, if present in the collection or place where
|
||||||
new element with value (key) should be inserted.
|
new element with value (key) should be inserted.
|
||||||
*/
|
*/
|
||||||
template <typename IterT, typename KeyT, typename CmpT>
|
template <typename CmpLess, typename IterT, typename KeyT>
|
||||||
static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, CmpT cmp)
|
static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, CmpLess cmp)
|
||||||
{
|
{
|
||||||
size_t down = 0, up = (end - beg);
|
size_t down = 0, up = (end - beg);
|
||||||
while(down < up)
|
while(down < up)
|
||||||
@ -3387,23 +3387,18 @@ bool VmaVectorRemoveSorted(VectorT& vector, const typename VectorT::value_type&
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename CmpLess, typename VectorT>
|
template<typename CmpLess, typename IterT, typename KeyT>
|
||||||
size_t VmaVectorFindSorted(const VectorT& vector, const typename VectorT::value_type& value)
|
IterT VmaVectorFindSorted(const IterT& beg, const IterT& end, const KeyT& value)
|
||||||
{
|
{
|
||||||
CmpLess comparator;
|
CmpLess comparator;
|
||||||
typename VectorT::iterator it = VmaBinaryFindFirstNotLess(
|
typename IterT it = VmaBinaryFindFirstNotLess<CmpLess, IterT, KeyT>(
|
||||||
vector.data(),
|
beg, end, value, comparator);
|
||||||
vector.data() + vector.size(),
|
if(it == end ||
|
||||||
value,
|
!comparator(*it, value) && !comparator(value, *it))
|
||||||
comparator);
|
|
||||||
if(it != vector.size() && !comparator(*it, value) && !comparator(value, *it))
|
|
||||||
{
|
{
|
||||||
return it - vector.begin();
|
return it;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return vector.size();
|
|
||||||
}
|
}
|
||||||
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -4338,6 +4333,22 @@ struct VmaSuballocation
|
|||||||
VmaSuballocationType type;
|
VmaSuballocationType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Comparator for offsets.
|
||||||
|
struct VmaSuballocationOffsetLess
|
||||||
|
{
|
||||||
|
bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const
|
||||||
|
{
|
||||||
|
return lhs.offset < rhs.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct VmaSuballocationOffsetGreater
|
||||||
|
{
|
||||||
|
bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const
|
||||||
|
{
|
||||||
|
return lhs.offset > rhs.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef VmaList< VmaSuballocation, VmaStlAllocator<VmaSuballocation> > VmaSuballocationList;
|
typedef VmaList< VmaSuballocation, VmaStlAllocator<VmaSuballocation> > VmaSuballocationList;
|
||||||
|
|
||||||
// Cost of one additional allocation lost, as equivalent in bytes.
|
// Cost of one additional allocation lost, as equivalent in bytes.
|
||||||
@ -8754,7 +8765,7 @@ void VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last allocation in 2-part ring buffer or top of 2nd stack (same logic).
|
// Last allocation in 2-part ring buffer or top of upper stack (same logic).
|
||||||
if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ||
|
if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ||
|
||||||
m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
|
m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
|
||||||
{
|
{
|
||||||
@ -8781,16 +8792,20 @@ void VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Item from the middle of 1st vector.
|
// Item from the middle of 1st vector.
|
||||||
// TODO optimize using binary search.
|
|
||||||
for(size_t i = m_1stNullItemsBeginCount + 1; i < suballocations1st.size(); ++i)
|
|
||||||
{
|
{
|
||||||
VmaSuballocation& currSuballoc = suballocations1st[i];
|
VmaSuballocation refSuballoc;
|
||||||
if(currSuballoc.offset == offset)
|
refSuballoc.offset = offset;
|
||||||
|
// Rest of members stays uninitialized intentionally for better performance.
|
||||||
|
SuballocationVectorType::iterator it = VmaVectorFindSorted<VmaSuballocationOffsetLess>(
|
||||||
|
suballocations1st.begin() + m_1stNullItemsBeginCount,
|
||||||
|
suballocations1st.end(),
|
||||||
|
refSuballoc);
|
||||||
|
if(it != suballocations1st.end())
|
||||||
{
|
{
|
||||||
currSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
|
it->type = VMA_SUBALLOCATION_TYPE_FREE;
|
||||||
currSuballoc.hAllocation = VK_NULL_HANDLE;
|
it->hAllocation = VK_NULL_HANDLE;
|
||||||
++m_1stNullItemsMiddleCount;
|
++m_1stNullItemsMiddleCount;
|
||||||
m_SumFreeSize += currSuballoc.size;
|
m_SumFreeSize += it->size;
|
||||||
CleanupAfterFree();
|
CleanupAfterFree();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -8799,21 +8814,22 @@ void VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset)
|
|||||||
if(m_2ndVectorMode != SECOND_VECTOR_EMPTY)
|
if(m_2ndVectorMode != SECOND_VECTOR_EMPTY)
|
||||||
{
|
{
|
||||||
// Item from the middle of 2nd vector.
|
// Item from the middle of 2nd vector.
|
||||||
// TODO optimize using binary search. Careful when DOUBLE_STACK - suballocations are then sorted in reverse order of offsets.
|
VmaSuballocation refSuballoc;
|
||||||
for(size_t i = 0; i < suballocations2nd.size() - 1; ++i)
|
refSuballoc.offset = offset;
|
||||||
|
// Rest of members stays uninitialized intentionally for better performance.
|
||||||
|
SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?
|
||||||
|
VmaVectorFindSorted<VmaSuballocationOffsetLess>(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc) :
|
||||||
|
VmaVectorFindSorted<VmaSuballocationOffsetGreater>(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc);
|
||||||
|
if(it != suballocations2nd.end())
|
||||||
{
|
{
|
||||||
VmaSuballocation& currSuballoc = suballocations2nd[i];
|
it->type = VMA_SUBALLOCATION_TYPE_FREE;
|
||||||
if(currSuballoc.offset == offset)
|
it->hAllocation = VK_NULL_HANDLE;
|
||||||
{
|
|
||||||
currSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
|
|
||||||
currSuballoc.hAllocation = VK_NULL_HANDLE;
|
|
||||||
++m_2ndNullItemsCount;
|
++m_2ndNullItemsCount;
|
||||||
m_SumFreeSize += currSuballoc.size;
|
m_SumFreeSize += it->size;
|
||||||
CleanupAfterFree();
|
CleanupAfterFree();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
VMA_ASSERT(0 && "Allocation to free not found in linear allocator!");
|
VMA_ASSERT(0 && "Allocation to free not found in linear allocator!");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user