mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
Merge pull request #8041 from Jupeyy/pr_small_alloc_fix_vk
Search __most__ fitting allocation, not _first_ fitting
This commit is contained in:
commit
350acae56b
|
@ -30,6 +30,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <SDL_video.h>
|
#include <SDL_video.h>
|
||||||
|
@ -160,6 +161,20 @@ class CCommandProcessorFragment_Vulkan : public CCommandProcessorFragment_GLBase
|
||||||
size_t m_OffsetToAlign;
|
size_t m_OffsetToAlign;
|
||||||
SMemoryHeapElement *m_pElementInHeap;
|
SMemoryHeapElement *m_pElementInHeap;
|
||||||
[[nodiscard]] bool operator>(const SMemoryHeapQueueElement &Other) const { return m_AllocationSize > Other.m_AllocationSize; }
|
[[nodiscard]] bool operator>(const SMemoryHeapQueueElement &Other) const { return m_AllocationSize > Other.m_AllocationSize; }
|
||||||
|
struct SMemoryHeapQueueElementFind
|
||||||
|
{
|
||||||
|
// respects alignment requirements
|
||||||
|
constexpr bool operator()(const SMemoryHeapQueueElement &Val, const std::pair<size_t, size_t> &Other) const
|
||||||
|
{
|
||||||
|
auto AllocSize = Other.first;
|
||||||
|
auto AllocAlignment = Other.second;
|
||||||
|
size_t ExtraSizeAlign = Val.m_OffsetInHeap % AllocAlignment;
|
||||||
|
if(ExtraSizeAlign != 0)
|
||||||
|
ExtraSizeAlign = AllocAlignment - ExtraSizeAlign;
|
||||||
|
size_t RealAllocSize = AllocSize + ExtraSizeAlign;
|
||||||
|
return Val.m_AllocationSize < RealAllocSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::multiset<SMemoryHeapQueueElement, std::greater<>> TMemoryHeapQueue;
|
typedef std::multiset<SMemoryHeapQueueElement, std::greater<>> TMemoryHeapQueue;
|
||||||
|
@ -202,24 +217,32 @@ class CCommandProcessorFragment_Vulkan : public CCommandProcessorFragment_GLBase
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// calculate the alignment
|
|
||||||
size_t ExtraSizeAlign = m_Elements.begin()->m_OffsetInHeap % AllocAlignment;
|
|
||||||
if(ExtraSizeAlign != 0)
|
|
||||||
ExtraSizeAlign = AllocAlignment - ExtraSizeAlign;
|
|
||||||
size_t RealAllocSize = AllocSize + ExtraSizeAlign;
|
|
||||||
|
|
||||||
// check if there is enough space in this instance
|
// check if there is enough space in this instance
|
||||||
if(m_Elements.begin()->m_AllocationSize < RealAllocSize)
|
if(bool(SMemoryHeapQueueElement::SMemoryHeapQueueElementFind{}(*m_Elements.begin(), std::make_pair(AllocSize, AllocAlignment))))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto TopEl = *m_Elements.begin();
|
// see SMemoryHeapQueueElement::operator>
|
||||||
|
SMemoryHeapQueueElement FindAllocSize;
|
||||||
|
FindAllocSize.m_AllocationSize = AllocSize;
|
||||||
|
// find upper bound for a allocation size
|
||||||
|
auto Upper = m_Elements.upper_bound(FindAllocSize);
|
||||||
|
// then find the first entry that respects alignment, this is a linear search!
|
||||||
|
auto FoundEl = std::lower_bound(std::make_reverse_iterator(Upper), m_Elements.rend(), std::make_pair(AllocSize, AllocAlignment), SMemoryHeapQueueElement::SMemoryHeapQueueElementFind{});
|
||||||
|
|
||||||
|
auto TopEl = *FoundEl;
|
||||||
m_Elements.erase(TopEl.m_pElementInHeap->m_InQueue);
|
m_Elements.erase(TopEl.m_pElementInHeap->m_InQueue);
|
||||||
|
|
||||||
TopEl.m_pElementInHeap->m_InUse = true;
|
TopEl.m_pElementInHeap->m_InUse = true;
|
||||||
|
|
||||||
|
// calculate the real alloc size + alignment offset
|
||||||
|
size_t ExtraSizeAlign = TopEl.m_OffsetInHeap % AllocAlignment;
|
||||||
|
if(ExtraSizeAlign != 0)
|
||||||
|
ExtraSizeAlign = AllocAlignment - ExtraSizeAlign;
|
||||||
|
size_t RealAllocSize = AllocSize + ExtraSizeAlign;
|
||||||
|
|
||||||
// the heap element gets children
|
// the heap element gets children
|
||||||
TopEl.m_pElementInHeap->m_pLeft = std::make_unique<SMemoryHeapElement>();
|
TopEl.m_pElementInHeap->m_pLeft = std::make_unique<SMemoryHeapElement>();
|
||||||
TopEl.m_pElementInHeap->m_pLeft->m_AllocationSize = RealAllocSize;
|
TopEl.m_pElementInHeap->m_pLeft->m_AllocationSize = RealAllocSize;
|
||||||
|
|
Loading…
Reference in a new issue