From 5b09160049d6247e4495bf4b855f8ce3223bdb1e Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Tue, 25 Nov 2025 20:39:18 +0800 Subject: [PATCH] hlsf wrong slicing solving --- .../Painting/Structural Highlighting.xml | 6 - .../HighPerformance/Memory/BufferStack.cs | 11 +- .../Memory/HLSFAllocationHandle.cs | 15 +-- .../Memory/HLSFAllocator.Alloc.cs | 112 +++++++++--------- .../Memory/HLSFAllocator.BucketNode.cs | 67 +++++------ .../Memory/HLSFAllocator.Debug.cs | 6 +- .../Memory/HLSFAllocator.SegmentEntry.cs | 56 +++++---- .../HighPerformance/Memory/HLSFAllocator.cs | 17 ++- StgSharp.Common/StgSharp.Common.csproj | 16 ++- .../StgSharp.Mathematics.csproj | 1 + StgSharp.Model/StgSharp.Model.csproj | 1 + StgSharp.Native/StgSharp.Native.vcxproj | 44 +++++++ StgSharp.Script/StgSharp.Script.csproj | 1 + .../StgSharp.TerminalDialogue.csproj | 9 ++ StgSharpDebug/StgSharpDebug.csproj | 12 +- StgSharpDevelop.sln | 31 +++++ 16 files changed, 256 insertions(+), 149 deletions(-) delete mode 100644 .cr/personal/Editor/Painting/Structural Highlighting.xml diff --git a/.cr/personal/Editor/Painting/Structural Highlighting.xml b/.cr/personal/Editor/Painting/Structural Highlighting.xml deleted file mode 100644 index 347228e8..00000000 --- a/.cr/personal/Editor/Painting/Structural Highlighting.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - False - - \ No newline at end of file diff --git a/StgSharp.Common/HighPerformance/Memory/BufferStack.cs b/StgSharp.Common/HighPerformance/Memory/BufferStack.cs index 564ad06b..ed6ae63d 100644 --- a/StgSharp.Common/HighPerformance/Memory/BufferStack.cs +++ b/StgSharp.Common/HighPerformance/Memory/BufferStack.cs @@ -32,7 +32,7 @@ using System.Runtime.InteropServices; namespace StgSharp.HighPerformance.Memory { [CollectionBuilder(typeof(BufferStackBuilder), nameof(BufferStackBuilder.Create))] - public unsafe class BufferStack : IDisposable where T: unmanaged + public unsafe class BufferStack : IDisposable where T : unmanaged { private byte* _buffer; @@ -40,9 +40,7 @@ namespace StgSharp.HighPerformance.Memory public BufferStack(int capacity) { - if (capacity <= 0) { - throw new ArgumentOutOfRangeException(nameof(capacity)); - } + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(capacity); AllocateBuffer(capacity); } @@ -124,9 +122,8 @@ namespace StgSharp.HighPerformance.Memory T* dataStart = (T*)(_buffer + sizeof(Header)); fixed (T* sourcePtr = span) { - Buffer.MemoryCopy(sourcePtr, dataStart, - header->Capacity * (nuint)sizeof(T), - (nuint)span.Length * (nuint)sizeof(T)); + Buffer.MemoryCopy(sourcePtr, dataStart, header->Capacity * (nuint)sizeof(T), + (nuint)span.Length * (nuint)sizeof(T)); } header->Top = (nuint)span.Length; diff --git a/StgSharp.Common/HighPerformance/Memory/HLSFAllocationHandle.cs b/StgSharp.Common/HighPerformance/Memory/HLSFAllocationHandle.cs index 4bb75469..6f97bdf0 100644 --- a/StgSharp.Common/HighPerformance/Memory/HLSFAllocationHandle.cs +++ b/StgSharp.Common/HighPerformance/Memory/HLSFAllocationHandle.cs @@ -36,36 +36,31 @@ using Allocator = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAlloca namespace StgSharp.HighPerformance.Memory { - public unsafe struct HybridLayerSegregatedFitAllocationHandle + public readonly unsafe struct HybridLayerSegregatedFitAllocationHandle { - internal readonly byte* BufferPointer; internal readonly Allocator.Entry* EntryHandle; public readonly uint AllocSize; internal HybridLayerSegregatedFitAllocationHandle(Allocator.Entry* handle, uint s) { EntryHandle = handle; - BufferPointer = (byte*)handle->Position; + Pointer = (byte*)handle->Position; AllocSize = s; } public readonly ref byte this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref BufferPointer[index]; + get => ref Pointer[index]; } - public readonly byte* Pointer - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => BufferPointer; - } + public readonly byte* Pointer { get; init; } public readonly Span BufferHandle { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new((byte*) EntryHandle->Position, (int)AllocSize); + get => new(Pointer, (int)AllocSize); } public readonly Enumerator GetEnumerator() diff --git a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Alloc.cs b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Alloc.cs index 99b6a755..be6d86df 100644 --- a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Alloc.cs +++ b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Alloc.cs @@ -80,61 +80,26 @@ namespace StgSharp.HighPerformance.Memory private void SliceMemory(Entry* e, int offset) { Entry* current = e; - ulong n = e->NextNear; + Entry* n = e->NextNear; Entry* next = e; ulong originOffset = e->Position - (ulong)m_Buffer; ulong finalOffset = originOffset + (ulong)offset; ulong end = e->Position + e->Size; + ulong endOffset = end - (ulong)m_Buffer; int remainSize = (int)(e->Size - offset); + // get level of left edge int minLevel = int.Max((BitOperations.TrailingZeroCount(finalOffset) - 6) / 2, 0); int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel; for (; i < levelSizeArray.Length; i++) { int levelSize = levelSizeArray[i]; - ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1); - int blockCount = (int)((ulong.Min(board, end) - board) / (ulong)levelSize); - if (blockCount == 0) - { - break; - } - int s = blockCount * levelSize; - - // create and init new entry - Entry* newEntry = (Entry*)_entries.Allocate(); - newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset); - newEntry->Size = (uint)s; - BucketNode* bucket = (BucketNode*)newEntry->Position; - bucket->EntryRef = newEntry; - - // link new entry - newEntry->PreviousNear = (ulong)current; - newEntry->NextNear = n; - current->NextNear = (ulong)newEntry; - next->PreviousNear = (ulong)newEntry; - - newEntry->Level = i; - PushLevel(i, blockCount - 1, bucket); - - // set new entry - Entry* old = current; - current = newEntry; - - finalOffset += (ulong)s; - remainSize -= s; - } - - if (remainSize <= 0) { - return; - } - - for (i -= 1; i >= 0; i--) - { - int levelSize = levelSizeArray[i]; - ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1); - int blockCount = (int)((ulong.Min(board, end) - finalOffset) / (ulong)levelSize); + ulong levelLong = (ulong)levelSize; + ulong levelUpper = levelLong * 4; + ulong board = (finalOffset + levelUpper - 1) / levelUpper * levelUpper; + int blockCount = (int)((board - ulong.Min(finalOffset, endOffset)) / levelLong); if (blockCount == 0) { continue; @@ -149,11 +114,50 @@ namespace StgSharp.HighPerformance.Memory bucket->EntryRef = newEntry; // link new entry - newEntry->PreviousNear = (ulong)current; + newEntry->PreviousNear = current; newEntry->NextNear = n; - current->NextNear = (ulong)newEntry; + current->NextNear = newEntry; + next->PreviousNear = newEntry; + + newEntry->Level = i; + PushLevel(i, blockCount - 1, bucket); + + // set new entry + Entry* old = current; + current = newEntry; + + finalOffset += (ulong)s; + remainSize -= s; + if (remainSize <= 0) { + return; + } + } + + for (i -= 1; i >= 0; i--) + { + int levelSize = levelSizeArray[i]; + ulong levelLong = (ulong)levelSize; + ulong board = endOffset / levelLong * levelLong; + int blockCount = (int)((board - finalOffset) / (ulong)levelSize); + if (blockCount == 0) + { + continue; + } + int s = blockCount * levelSize; + + // create and init new entry + Entry* newEntry = (Entry*)_entries.Allocate(); + newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset); + newEntry->Size = (uint)s; + BucketNode* bucket = (BucketNode*)newEntry->Position; + bucket->EntryRef = newEntry; + + // link new entry + newEntry->PreviousNear = current; + newEntry->NextNear = n; + current->NextNear = newEntry; if (next != null) { - next->PreviousNear = (ulong)newEntry; + next->PreviousNear = newEntry; } newEntry->Level = i; @@ -166,6 +170,10 @@ namespace StgSharp.HighPerformance.Memory // update lock and data finalOffset += (ulong)s; remainSize -= s; + if (remainSize <= 0) + { + break; + } } } @@ -184,10 +192,8 @@ namespace StgSharp.HighPerformance.Memory nuint blockSize = (nuint)levelSizeArray[^1] * 2; // Use last level size (16MB) nuint newPos = pos + blockSize; - ulong p; Entry* previous; - p = _spareMemory->PreviousNear; - previous = (Entry*)p; + previous = _spareMemory->PreviousNear; if (_spareMemory->Size <= 0) { handle = null; @@ -199,7 +205,7 @@ namespace StgSharp.HighPerformance.Memory { newPos = (nuint)m_Buffer + _size; // Clamp to maximum buffer size blockSize = _spareMemory->Size; - p = 0; + previous = null; } // Try to allocate new Entry from slab allocator @@ -216,11 +222,11 @@ namespace StgSharp.HighPerformance.Memory // PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b); // update position linked list - handle->NextNear = (ulong)_spareMemory; - handle->PreviousNear = p; - _spareMemory->PreviousNear = (ulong)handle; // Replace Volatile.Write with direct access + handle->NextNear = _spareMemory; + handle->PreviousNear = previous; + _spareMemory->PreviousNear = handle; // Replace Volatile.Write with direct access if (previous != null) { - previous->NextNear = (ulong)handle; + previous->NextNear = handle; } return true; diff --git a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.BucketNode.cs b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.BucketNode.cs index e4a5ebb6..97acc2f0 100644 --- a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.BucketNode.cs +++ b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.BucketNode.cs @@ -50,27 +50,27 @@ namespace StgSharp.HighPerformance.Memory return; } - int index = (3 * levelIndex) + sizeIndex; - if (_bucketHeads[index] == EmptyHandle) + Index index = (levelIndex > MaxLevel) ? ^1 : (3 * levelIndex) + sizeIndex; + if (_bucketHeads[index] == (BucketNode*)null) { - _bucketHeads[index] = (nuint)node; + _bucketHeads[index] = node; node->IsInBucket = true; - node->NextLevel = EmptyHandle; - node->PreviousLevel = EmptyHandle; + node->NextLevel = null; + node->PreviousLevel = null; // Console.WriteLine($"Push to empty level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}"); return; } else { - ulong head = _bucketHeads[index]; + BucketNode* head = _bucketHeads[index]; node->NextLevel = head; - BucketNode* headNode = (BucketNode*)head; + BucketNode* headNode = head; node->IsInBucket = true; // Console.WriteLine($"Push to head of level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}, previous head is at {head}"); if (headNode != null) { - headNode->PreviousLevel = (ulong)node; + headNode->PreviousLevel = node; } return; } @@ -78,29 +78,27 @@ namespace StgSharp.HighPerformance.Memory private void RemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node) { - int index = (3 * levelIndex) + sizeIndex; + Index index = (levelIndex > MaxLevel) ? ^1 : (3 * levelIndex) + sizeIndex; - if ((BucketNode*)_bucketHeads[index] == node) + if (_bucketHeads[index] == node) { if (TryPopLevel(levelIndex, sizeIndex, out _)) { return; } } - ulong p = node->PreviousLevel; - ulong n = node->NextLevel; - BucketNode* previous = (BucketNode*)p; - BucketNode* next = (BucketNode*)n; + BucketNode* previous = node->PreviousLevel; + BucketNode* next = node->NextLevel; if (previous != null) { - previous->NextLevel = n; + previous->NextLevel = next; } if (next != null) { - next->PreviousLevel = p; + next->PreviousLevel = previous; } - node->NextLevel = EmptyHandle; - node->PreviousLevel = EmptyHandle; + node->NextLevel = (BucketNode*)null; + node->PreviousLevel = (BucketNode*)null; node->IsInBucket = false; return; } @@ -109,8 +107,7 @@ namespace StgSharp.HighPerformance.Memory { int index = (3 * levelIndex) + sizeIndex; - ulong h = _bucketHeads[index]; - BucketNode* head = (BucketNode*)h; + BucketNode* head = _bucketHeads[index]; if (head == null) { @@ -119,20 +116,20 @@ namespace StgSharp.HighPerformance.Memory } // Console.WriteLine($"level popped from level {levelIndex} {sizeIndex}, node is at {(ulong)head}"); - BucketNode* next = (BucketNode*)head->NextLevel; + BucketNode* next = head->NextLevel; if (next == null) { - _bucketHeads[index] = EmptyHandle; + _bucketHeads[index] = null; node = head; return true; } _bucketHeads[index] = head->NextLevel; node = head; node->IsInBucket = false; - node->NextLevel = EmptyHandle; + node->NextLevel = null; if (next != null) { - next->PreviousLevel = EmptyHandle; + next->PreviousLevel = null; } return true; } @@ -140,24 +137,22 @@ namespace StgSharp.HighPerformance.Memory private bool TryRemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node) { int index = (3 * levelIndex) + sizeIndex; - if ((BucketNode*) _bucketHeads[index] == node) { + if (_bucketHeads[index] == node) { return TryPopLevel(levelIndex, sizeIndex, out _); } - ulong p = node->PreviousLevel; - ulong n = node->NextLevel; - BucketNode* previous = (BucketNode*)p; - BucketNode* next = (BucketNode*)n; + BucketNode* previous = node->PreviousLevel; + BucketNode* next = node->NextLevel; if (previous != null) { - previous->NextLevel = n; + previous->NextLevel = next; } if (next != null) { - next->PreviousLevel = p; + next->PreviousLevel = previous; } - node->NextLevel = EmptyHandle; - node->PreviousLevel = EmptyHandle; + node->NextLevel = null; + node->PreviousLevel = null; node->IsInBucket = false; @@ -173,10 +168,10 @@ namespace StgSharp.HighPerformance.Memory { [FieldOffset(0)] internal Entry* EntryRef; // Pointer to corresponding Entry + // [FieldOffset(16)] internal ulong LockBuffer; + [FieldOffset(8)] internal BucketNode* NextLevel; // Bucket stack linked list: next pointer + [FieldOffset(24)] internal BucketNode* PreviousLevel; // Bucket stack linked list: previous pointer [FieldOffset(32)] internal bool IsInBucket; // Whether in bucket - [FieldOffset(16)] internal ulong LockBuffer; - [FieldOffset(8)] internal ulong NextLevel; // Bucket stack linked list: next pointer - [FieldOffset(24)] internal ulong PreviousLevel; // Bucket stack linked list: previous pointer } diff --git a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Debug.cs b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Debug.cs index 4bbecc9e..7de08a83 100644 --- a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Debug.cs +++ b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.Debug.cs @@ -46,7 +46,7 @@ namespace StgSharp.HighPerformance.Memory while (cur != null) { Console.WriteLine(EntryToString(cur)); - cur = (Entry*)cur->PreviousNear; + cur = cur->PreviousNear; if (singleStep) { Console.ReadKey(); } @@ -63,7 +63,7 @@ namespace StgSharp.HighPerformance.Memory while (cur != null) { layout.Push(EntryToString(cur)); - cur = (Entry*)cur->PreviousNear; + cur = cur->PreviousNear; } return layout; } @@ -72,7 +72,7 @@ namespace StgSharp.HighPerformance.Memory private static string EntryToString(Entry* e) { BucketNode* b = (BucketNode*)e->Position; - return $"{e->PreviousNear}<-- Position{(ulong)e} Bucket:{{{e->Position},{e->Level},{e->Size}}} -->{e->NextNear}"; + return $"{(ulong)e->PreviousNear}<-- Position{(ulong)e} Bucket:{{{e->Position},{e->Level},{e->Size}}} -->{(ulong)e->NextNear}"; } } diff --git a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.SegmentEntry.cs b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.SegmentEntry.cs index c816515a..bd56db6d 100644 --- a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.SegmentEntry.cs +++ b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.SegmentEntry.cs @@ -25,6 +25,7 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -50,6 +51,7 @@ namespace StgSharp.HighPerformance.Memory /// private bool AssertBackwardBoundary(ulong currentOffset, Entry* target, int level) { + level = int.Min(level, MaxLevel); int nextLevelSize = levelSizeArray[level] * 4; ulong targetHead = target->Position - (ulong)m_Buffer; return (currentOffset / (ulong)nextLevelSize) == (targetHead / (ulong)nextLevelSize); @@ -72,6 +74,7 @@ namespace StgSharp.HighPerformance.Memory /// private bool AssertForwardBoundary(ulong currentOffset, Entry* target, int level) { + level = int.Min(level, MaxLevel); int nextLevelSize = levelSizeArray[level] * 4; ulong targetTail = target->Position - (ulong)m_Buffer + target->Size - 1; return (currentOffset / (ulong)nextLevelSize) == (targetTail / (ulong)nextLevelSize); @@ -83,6 +86,7 @@ namespace StgSharp.HighPerformance.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] private int DetermineSegmentIndex(uint size, int level) { + level = int.Min(level, MaxLevel); return (int)(size - 1) / levelSizeArray[level]; } @@ -113,7 +117,7 @@ namespace StgSharp.HighPerformance.Memory int originLevel = entry->Level; int segment = DetermineSegmentIndex(size, originLevel); - RemoveFromBucket(originLevel, segment, (BucketNode*)entry->Position); + // RemoveFromBucket(originLevel, segment, (BucketNode*)entry->Position); do { @@ -121,8 +125,7 @@ namespace StgSharp.HighPerformance.Memory while (true) { // backward merging - simplified to single attempt - ulong p = entry->PreviousNear; - Entry* prev = (Entry*)p; + Entry* prev = entry->PreviousNear; // compute offset of current block and base position ulong currentOffset = entry->Position - (ulong)m_Buffer; @@ -138,23 +141,24 @@ namespace StgSharp.HighPerformance.Memory } // Update linked list - Entry* prevPrev = (Entry*)prev->PreviousNear; + /* + Entry* prevPrev = prev->PreviousNear; if (prevPrev != null) { - prevPrev->NextNear = (ulong)entry; + prevPrev->NextNear = entry; } - entry->PreviousNear = (ulong)prevPrev; + entry->PreviousNear = prevPrev; + /**/ // Merge entry->Position = prev->Position; entry->Size += prev->Size; - RecycleEntry(prev); + RemoveFromPositionChain(prev); } while (true) { // forward merging - simplified to single attempt - ulong n = entry->NextNear; - Entry* next = (Entry*)n; + Entry* next = entry->NextNear; ulong currentOffset = entry->Position - (ulong)m_Buffer; @@ -169,15 +173,17 @@ namespace StgSharp.HighPerformance.Memory } // Update linked list - Entry* nextNext = (Entry*)next->NextNear; + /* + Entry* nextNext = next->NextNear; if (nextNext != null) { - nextNext->PreviousNear = (ulong)entry; + nextNext->PreviousNear = entry; } - entry->NextNear = (ulong)nextNext; + entry->NextNear = nextNext; + /**/ // Merge entry->Size += next->Size; - RecycleEntry(next); + RemoveFromPositionChain(next); } entry->Level = GetLevelFromSize(entry->Size); } while (originLevel < entry->Level); @@ -189,8 +195,10 @@ namespace StgSharp.HighPerformance.Memory return; } - entry->PreviousNear = EmptyHandle; - entry->NextNear = EmptyHandle; + entry->PreviousNear = null; + entry->NextNear = null; + + // Console.WriteLine("entry recycled."); _entries.Free((nuint)entry); } @@ -199,8 +207,8 @@ namespace StgSharp.HighPerformance.Memory /// private void RemoveFromPositionChain(Entry* entry) { - Entry* prev = (Entry*)entry->PreviousNear; - Entry* next = (Entry*)entry->NextNear; + Entry* prev = entry->PreviousNear; + Entry* next = entry->NextNear; if (prev != null) { prev->NextNear = entry->NextNear; @@ -210,8 +218,10 @@ namespace StgSharp.HighPerformance.Memory } // Clear node pointers - entry->NextNear = EmptyHandle; - entry->PreviousNear = EmptyHandle; + entry->NextNear = null; + entry->PreviousNear = null; + + // Console.WriteLine("entry recycled."); _entries.Free((nuint)entry); } @@ -223,11 +233,11 @@ namespace StgSharp.HighPerformance.Memory internal struct Entry { + [FieldOffset(8)] internal Entry* NextNear; // Position linked list: next pointer + [FieldOffset(16)] internal Entry* PreviousNear; // Position linked list: previous pointer + [FieldOffset(28)] internal int Level; // Level of the block in the allocator [FieldOffset(24)] internal uint Size; // Block size information - [FieldOffset(32)] internal ulong LockBuffer; - [FieldOffset(8)] internal ulong NextNear; // Position linked list: next pointer - [FieldOffset(16)] internal ulong PreviousNear; // Position linked list: previous pointer [FieldOffset(32)] public EntryState State; [FieldOffset(0)] public nuint Position; // Memory block position @@ -246,7 +256,7 @@ namespace StgSharp.HighPerformance.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsNullOrEmptyEntryIndex(ulong index) { - return index == EmptyHandle; + return index == 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.cs b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.cs index 5fe3b5ce..d736763e 100644 --- a/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.cs +++ b/StgSharp.Common/HighPerformance/Memory/HLSFAllocator.cs @@ -27,6 +27,7 @@ // ----------------------------------------------------------------------- using System; using System.Buffers; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -35,10 +36,8 @@ namespace StgSharp.HighPerformance.Memory public unsafe partial class HybridLayerSegregatedFitAllocator : IDisposable { - private const nuint EmptyHandle = 0; - // Bucket system field - directly in main allocator class - private ulong[] _bucketHeads; + private BucketNode*[] _bucketHeads; private Entry* _spareMemory; private readonly byte* m_Buffer; @@ -57,12 +56,12 @@ namespace StgSharp.HighPerformance.Memory m_Buffer = (byte*)NativeMemory.AlignedAlloc(byteSize, 16); _align = 16; - _bucketHeads = new ulong[levelSizeArray.Length * 3]; + _bucketHeads = new BucketNode*[levelSizeArray.Length * 3 + 1]; _spareMemory = (Entry*)_entries.Allocate(); _spareMemory->State = EntryState.Empty; - _spareMemory->PreviousNear = EmptyHandle; - _spareMemory->NextNear = EmptyHandle; + _spareMemory->PreviousNear = null; + _spareMemory->NextNear = null; _spareMemory->Position = (nuint)m_Buffer; _spareMemory->Size = (uint)byteSize; } @@ -78,12 +77,12 @@ namespace StgSharp.HighPerformance.Memory _align = align; _size = byteSize; - _bucketHeads = new ulong[levelSizeArray.Length * 3]; + _bucketHeads = new BucketNode*[levelSizeArray.Length * 3]; _spareMemory = (Entry*)_entries.Allocate(); _spareMemory->State = EntryState.Empty; - _spareMemory->PreviousNear = EmptyHandle; - _spareMemory->NextNear = EmptyHandle; + _spareMemory->PreviousNear = null; + _spareMemory->NextNear = null; _spareMemory->Position = (nuint)m_Buffer; _spareMemory->Size = (uint)byteSize; } diff --git a/StgSharp.Common/StgSharp.Common.csproj b/StgSharp.Common/StgSharp.Common.csproj index 2d3616b8..e3c96fde 100644 --- a/StgSharp.Common/StgSharp.Common.csproj +++ b/StgSharp.Common/StgSharp.Common.csproj @@ -14,7 +14,7 @@ preview-all Library enable - Debug;Release; + Debug;Release;PerformanceDebug @@ -60,6 +60,13 @@ True + + none + 1701;1702;0649;1591;0169 + False + True + + none 1701;1702;0649;1591;0169 @@ -67,6 +74,13 @@ True + + none + 1701;1702;0649;1591;0169 + False + True + + true true diff --git a/StgSharp.Mathematics/StgSharp.Mathematics.csproj b/StgSharp.Mathematics/StgSharp.Mathematics.csproj index 6f33de76..8495f4ac 100644 --- a/StgSharp.Mathematics/StgSharp.Mathematics.csproj +++ b/StgSharp.Mathematics/StgSharp.Mathematics.csproj @@ -7,6 +7,7 @@ Preview True x64;ARM64 + Debug;Release;PerformanceDebug diff --git a/StgSharp.Model/StgSharp.Model.csproj b/StgSharp.Model/StgSharp.Model.csproj index 52789748..0d74645a 100644 --- a/StgSharp.Model/StgSharp.Model.csproj +++ b/StgSharp.Model/StgSharp.Model.csproj @@ -10,6 +10,7 @@ True False True + Debug;Release;PerformanceDebug diff --git a/StgSharp.Native/StgSharp.Native.vcxproj b/StgSharp.Native/StgSharp.Native.vcxproj index b4d8f9a1..e5db6017 100644 --- a/StgSharp.Native/StgSharp.Native.vcxproj +++ b/StgSharp.Native/StgSharp.Native.vcxproj @@ -5,6 +5,10 @@ Debug x64 + + PerformanceDebug + x64 + Release x64 @@ -33,6 +37,13 @@ Unicode v143 + + DynamicLibrary + false + true + Unicode + v143 + @@ -44,6 +55,9 @@ + + + $(SolutionDir)build @@ -52,6 +66,10 @@ $(SolutionDir)build false + + $(SolutionDir)build + false + Level3 @@ -103,6 +121,32 @@ UseLinkTimeCodeGeneration + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Speed + All + Default + stdc11 + CompileAsC + true + $(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories) + + + Console + true + true + false + opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + LinkVerbose + UseLinkTimeCodeGeneration + + diff --git a/StgSharp.Script/StgSharp.Script.csproj b/StgSharp.Script/StgSharp.Script.csproj index 528cf895..317df04b 100644 --- a/StgSharp.Script/StgSharp.Script.csproj +++ b/StgSharp.Script/StgSharp.Script.csproj @@ -6,6 +6,7 @@ preview True x64 + Debug;Release;PerformanceDebug diff --git a/StgSharp.TerminalDialogue/StgSharp.TerminalDialogue.csproj b/StgSharp.TerminalDialogue/StgSharp.TerminalDialogue.csproj index 4b8b7eea..a1ecd2f3 100644 --- a/StgSharp.TerminalDialogue/StgSharp.TerminalDialogue.csproj +++ b/StgSharp.TerminalDialogue/StgSharp.TerminalDialogue.csproj @@ -14,12 +14,17 @@ x64 none x64 + Debug;Release;PerformanceDebug False + + False + + True @@ -28,6 +33,10 @@ False + + False + + True diff --git a/StgSharpDebug/StgSharpDebug.csproj b/StgSharpDebug/StgSharpDebug.csproj index ae37e1dd..9709df1a 100644 --- a/StgSharpDebug/StgSharpDebug.csproj +++ b/StgSharpDebug/StgSharpDebug.csproj @@ -17,7 +17,7 @@ False x64;ARM64 Always - Debug;Release; + Debug;Release;PerformanceDebug @@ -37,11 +37,21 @@ False + + True + False + + True False + + True + False + + true true diff --git a/StgSharpDevelop.sln b/StgSharpDevelop.sln index 0b62d83e..1811afab 100644 --- a/StgSharpDevelop.sln +++ b/StgSharpDevelop.sln @@ -34,6 +34,8 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 + PerformanceDebug|ARM64 = PerformanceDebug|ARM64 + PerformanceDebug|x64 = PerformanceDebug|x64 Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 EndGlobalSection @@ -42,6 +44,10 @@ Global {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Debug|ARM64.Build.0 = Debug|ARM64 {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Debug|x64.ActiveCfg = Debug|x64 {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Debug|x64.Build.0 = Debug|x64 + {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|ARM64 + {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|ARM64 + {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Release|ARM64.ActiveCfg = Release|ARM64 {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Release|ARM64.Build.0 = Release|ARM64 {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Release|x64.ActiveCfg = Release|x64 @@ -50,6 +56,10 @@ Global {610B992B-BB34-49C3-9993-676C595FC12E}.Debug|ARM64.Build.0 = Debug|ARM64 {610B992B-BB34-49C3-9993-676C595FC12E}.Debug|x64.ActiveCfg = Debug|x64 {610B992B-BB34-49C3-9993-676C595FC12E}.Debug|x64.Build.0 = Debug|x64 + {610B992B-BB34-49C3-9993-676C595FC12E}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|ARM64 + {610B992B-BB34-49C3-9993-676C595FC12E}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|ARM64 + {610B992B-BB34-49C3-9993-676C595FC12E}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {610B992B-BB34-49C3-9993-676C595FC12E}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.ActiveCfg = Release|ARM64 {610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.Build.0 = Release|ARM64 {610B992B-BB34-49C3-9993-676C595FC12E}.Release|x64.ActiveCfg = Release|x64 @@ -57,6 +67,10 @@ Global {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|ARM64.Build.0 = Debug|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.ActiveCfg = Debug|x64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.Build.0 = Debug|x64 + {20CBFF26-6746-402E-992C-7B643E9423EB}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|x64 + {20CBFF26-6746-402E-992C-7B643E9423EB}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|x64 + {20CBFF26-6746-402E-992C-7B643E9423EB}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {20CBFF26-6746-402E-992C-7B643E9423EB}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|ARM64.ActiveCfg = Release|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|ARM64.Build.0 = Release|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|x64.ActiveCfg = Release|x64 @@ -65,6 +79,10 @@ Global {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Debug|ARM64.Build.0 = Debug|ARM64 {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Debug|x64.ActiveCfg = Debug|x64 {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Debug|x64.Build.0 = Debug|x64 + {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|x64 + {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|x64 + {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Release|ARM64.ActiveCfg = Release|x64 {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Release|ARM64.Build.0 = Release|x64 {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Release|x64.ActiveCfg = Release|x64 @@ -73,6 +91,10 @@ Global {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Debug|ARM64.Build.0 = Debug|ARM64 {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Debug|x64.ActiveCfg = Debug|x64 {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Debug|x64.Build.0 = Debug|x64 + {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|x64 + {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|x64 + {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Release|ARM64.ActiveCfg = Release|x64 {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Release|ARM64.Build.0 = Release|x64 {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Release|x64.ActiveCfg = Release|x64 @@ -81,6 +103,10 @@ Global {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Debug|ARM64.Build.0 = Debug|x64 {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Debug|x64.ActiveCfg = Debug|x64 {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Debug|x64.Build.0 = Debug|x64 + {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|x64 + {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|x64 + {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Release|ARM64.ActiveCfg = Release|ARM64 {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Release|ARM64.Build.0 = Release|ARM64 {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Release|x64.ActiveCfg = Release|x64 @@ -89,9 +115,14 @@ Global {9946599F-4D34-440F-840D-F9443D5AEFAA}.Debug|ARM64.Build.0 = Debug|ARM64 {9946599F-4D34-440F-840D-F9443D5AEFAA}.Debug|x64.ActiveCfg = Debug|x64 {9946599F-4D34-440F-840D-F9443D5AEFAA}.Debug|x64.Build.0 = Debug|x64 + {9946599F-4D34-440F-840D-F9443D5AEFAA}.PerformanceDebug|ARM64.ActiveCfg = PerformanceDebug|ARM64 + {9946599F-4D34-440F-840D-F9443D5AEFAA}.PerformanceDebug|ARM64.Build.0 = PerformanceDebug|ARM64 + {9946599F-4D34-440F-840D-F9443D5AEFAA}.PerformanceDebug|x64.ActiveCfg = PerformanceDebug|x64 + {9946599F-4D34-440F-840D-F9443D5AEFAA}.PerformanceDebug|x64.Build.0 = PerformanceDebug|x64 {9946599F-4D34-440F-840D-F9443D5AEFAA}.Release|ARM64.ActiveCfg = Release|ARM64 {9946599F-4D34-440F-840D-F9443D5AEFAA}.Release|ARM64.Build.0 = Release|ARM64 {9946599F-4D34-440F-840D-F9443D5AEFAA}.Release|x64.ActiveCfg = Release|x64 + {9946599F-4D34-440F-840D-F9443D5AEFAA}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE