hlsf wrong slicing solving

This commit is contained in:
Youmu Liu
2025-11-25 20:39:18 +08:00
parent 7ef57d8f33
commit 5b09160049
16 changed files with 256 additions and 149 deletions
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Root Type="DevExpress.CodeRush.VisualizePlugins.StructuralHighlighting.Options.StructuralHighlightingOptions">
<Options Language="Neutral">
<Enabled>False</Enabled>
</Options>
</Root>
@@ -32,7 +32,7 @@ using System.Runtime.InteropServices;
namespace StgSharp.HighPerformance.Memory namespace StgSharp.HighPerformance.Memory
{ {
[CollectionBuilder(typeof(BufferStackBuilder), nameof(BufferStackBuilder.Create))] [CollectionBuilder(typeof(BufferStackBuilder), nameof(BufferStackBuilder.Create))]
public unsafe class BufferStack<T> : IDisposable where T: unmanaged public unsafe class BufferStack<T> : IDisposable where T : unmanaged
{ {
private byte* _buffer; private byte* _buffer;
@@ -40,9 +40,7 @@ namespace StgSharp.HighPerformance.Memory
public BufferStack(int capacity) public BufferStack(int capacity)
{ {
if (capacity <= 0) { ArgumentOutOfRangeException.ThrowIfNegativeOrZero(capacity);
throw new ArgumentOutOfRangeException(nameof(capacity));
}
AllocateBuffer(capacity); AllocateBuffer(capacity);
} }
@@ -124,9 +122,8 @@ namespace StgSharp.HighPerformance.Memory
T* dataStart = (T*)(_buffer + sizeof(Header)); T* dataStart = (T*)(_buffer + sizeof(Header));
fixed (T* sourcePtr = span) { fixed (T* sourcePtr = span) {
Buffer.MemoryCopy(sourcePtr, dataStart, Buffer.MemoryCopy(sourcePtr, dataStart, header->Capacity * (nuint)sizeof(T),
header->Capacity * (nuint)sizeof(T), (nuint)span.Length * (nuint)sizeof(T));
(nuint)span.Length * (nuint)sizeof(T));
} }
header->Top = (nuint)span.Length; header->Top = (nuint)span.Length;
@@ -36,36 +36,31 @@ using Allocator = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAlloca
namespace StgSharp.HighPerformance.Memory namespace StgSharp.HighPerformance.Memory
{ {
public unsafe struct HybridLayerSegregatedFitAllocationHandle public readonly unsafe struct HybridLayerSegregatedFitAllocationHandle
{ {
internal readonly byte* BufferPointer;
internal readonly Allocator.Entry* EntryHandle; internal readonly Allocator.Entry* EntryHandle;
public readonly uint AllocSize; public readonly uint AllocSize;
internal HybridLayerSegregatedFitAllocationHandle(Allocator.Entry* handle, uint s) internal HybridLayerSegregatedFitAllocationHandle(Allocator.Entry* handle, uint s)
{ {
EntryHandle = handle; EntryHandle = handle;
BufferPointer = (byte*)handle->Position; Pointer = (byte*)handle->Position;
AllocSize = s; AllocSize = s;
} }
public readonly ref byte this[int index] public readonly ref byte this[int index]
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref BufferPointer[index]; get => ref Pointer[index];
} }
public readonly byte* Pointer public readonly byte* Pointer { get; init; }
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => BufferPointer;
}
public readonly Span<byte> BufferHandle public readonly Span<byte> BufferHandle
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new((byte*) EntryHandle->Position, (int)AllocSize); get => new(Pointer, (int)AllocSize);
} }
public readonly Enumerator GetEnumerator() public readonly Enumerator GetEnumerator()
@@ -80,61 +80,26 @@ namespace StgSharp.HighPerformance.Memory
private void SliceMemory(Entry* e, int offset) private void SliceMemory(Entry* e, int offset)
{ {
Entry* current = e; Entry* current = e;
ulong n = e->NextNear; Entry* n = e->NextNear;
Entry* next = e; Entry* next = e;
ulong originOffset = e->Position - (ulong)m_Buffer; ulong originOffset = e->Position - (ulong)m_Buffer;
ulong finalOffset = originOffset + (ulong)offset; ulong finalOffset = originOffset + (ulong)offset;
ulong end = e->Position + e->Size; ulong end = e->Position + e->Size;
ulong endOffset = end - (ulong)m_Buffer;
int remainSize = (int)(e->Size - offset); int remainSize = (int)(e->Size - offset);
// get level of left edge
int minLevel = int.Max((BitOperations.TrailingZeroCount(finalOffset) - 6) / 2, 0); int minLevel = int.Max((BitOperations.TrailingZeroCount(finalOffset) - 6) / 2, 0);
int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel; int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel;
for (; i < levelSizeArray.Length; i++) for (; i < levelSizeArray.Length; i++)
{ {
int levelSize = levelSizeArray[i]; int levelSize = levelSizeArray[i];
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1); ulong levelLong = (ulong)levelSize;
int blockCount = (int)((ulong.Min(board, end) - board) / (ulong)levelSize); ulong levelUpper = levelLong * 4;
if (blockCount == 0) ulong board = (finalOffset + levelUpper - 1) / levelUpper * levelUpper;
{ int blockCount = (int)((board - ulong.Min(finalOffset, endOffset)) / levelLong);
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);
if (blockCount == 0) if (blockCount == 0)
{ {
continue; continue;
@@ -149,11 +114,50 @@ namespace StgSharp.HighPerformance.Memory
bucket->EntryRef = newEntry; bucket->EntryRef = newEntry;
// link new entry // link new entry
newEntry->PreviousNear = (ulong)current; newEntry->PreviousNear = current;
newEntry->NextNear = n; 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) { if (next != null) {
next->PreviousNear = (ulong)newEntry; next->PreviousNear = newEntry;
} }
newEntry->Level = i; newEntry->Level = i;
@@ -166,6 +170,10 @@ namespace StgSharp.HighPerformance.Memory
// update lock and data // update lock and data
finalOffset += (ulong)s; finalOffset += (ulong)s;
remainSize -= 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 blockSize = (nuint)levelSizeArray[^1] * 2; // Use last level size (16MB)
nuint newPos = pos + blockSize; nuint newPos = pos + blockSize;
ulong p;
Entry* previous; Entry* previous;
p = _spareMemory->PreviousNear; previous = _spareMemory->PreviousNear;
previous = (Entry*)p;
if (_spareMemory->Size <= 0) if (_spareMemory->Size <= 0)
{ {
handle = null; handle = null;
@@ -199,7 +205,7 @@ namespace StgSharp.HighPerformance.Memory
{ {
newPos = (nuint)m_Buffer + _size; // Clamp to maximum buffer size newPos = (nuint)m_Buffer + _size; // Clamp to maximum buffer size
blockSize = _spareMemory->Size; blockSize = _spareMemory->Size;
p = 0; previous = null;
} }
// Try to allocate new Entry from slab allocator // 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); // PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
// update position linked list // update position linked list
handle->NextNear = (ulong)_spareMemory; handle->NextNear = _spareMemory;
handle->PreviousNear = p; handle->PreviousNear = previous;
_spareMemory->PreviousNear = (ulong)handle; // Replace Volatile.Write with direct access _spareMemory->PreviousNear = handle; // Replace Volatile.Write with direct access
if (previous != null) { if (previous != null) {
previous->NextNear = (ulong)handle; previous->NextNear = handle;
} }
return true; return true;
@@ -50,27 +50,27 @@ namespace StgSharp.HighPerformance.Memory
return; return;
} }
int index = (3 * levelIndex) + sizeIndex; Index index = (levelIndex > MaxLevel) ? ^1 : (3 * levelIndex) + sizeIndex;
if (_bucketHeads[index] == EmptyHandle) if (_bucketHeads[index] == (BucketNode*)null)
{ {
_bucketHeads[index] = (nuint)node; _bucketHeads[index] = node;
node->IsInBucket = true; node->IsInBucket = true;
node->NextLevel = EmptyHandle; node->NextLevel = null;
node->PreviousLevel = EmptyHandle; node->PreviousLevel = null;
// Console.WriteLine($"Push to empty level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}"); // Console.WriteLine($"Push to empty level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}");
return; return;
} else } else
{ {
ulong head = _bucketHeads[index]; BucketNode* head = _bucketHeads[index];
node->NextLevel = head; node->NextLevel = head;
BucketNode* headNode = (BucketNode*)head; BucketNode* headNode = head;
node->IsInBucket = true; node->IsInBucket = true;
// Console.WriteLine($"Push to head of level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}, previous head is at {head}"); // Console.WriteLine($"Push to head of level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}, previous head is at {head}");
if (headNode != null) if (headNode != null)
{ {
headNode->PreviousLevel = (ulong)node; headNode->PreviousLevel = node;
} }
return; return;
} }
@@ -78,29 +78,27 @@ namespace StgSharp.HighPerformance.Memory
private void RemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node) 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 _)) { if (TryPopLevel(levelIndex, sizeIndex, out _)) {
return; return;
} }
} }
ulong p = node->PreviousLevel; BucketNode* previous = node->PreviousLevel;
ulong n = node->NextLevel; BucketNode* next = node->NextLevel;
BucketNode* previous = (BucketNode*)p;
BucketNode* next = (BucketNode*)n;
if (previous != null) { if (previous != null) {
previous->NextLevel = n; previous->NextLevel = next;
} }
if (next != null) { if (next != null) {
next->PreviousLevel = p; next->PreviousLevel = previous;
} }
node->NextLevel = EmptyHandle; node->NextLevel = (BucketNode*)null;
node->PreviousLevel = EmptyHandle; node->PreviousLevel = (BucketNode*)null;
node->IsInBucket = false; node->IsInBucket = false;
return; return;
} }
@@ -109,8 +107,7 @@ namespace StgSharp.HighPerformance.Memory
{ {
int index = (3 * levelIndex) + sizeIndex; int index = (3 * levelIndex) + sizeIndex;
ulong h = _bucketHeads[index]; BucketNode* head = _bucketHeads[index];
BucketNode* head = (BucketNode*)h;
if (head == null) if (head == null)
{ {
@@ -119,20 +116,20 @@ namespace StgSharp.HighPerformance.Memory
} }
// Console.WriteLine($"level popped from level {levelIndex} {sizeIndex}, node is at {(ulong)head}"); // 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) if (next == null)
{ {
_bucketHeads[index] = EmptyHandle; _bucketHeads[index] = null;
node = head; node = head;
return true; return true;
} }
_bucketHeads[index] = head->NextLevel; _bucketHeads[index] = head->NextLevel;
node = head; node = head;
node->IsInBucket = false; node->IsInBucket = false;
node->NextLevel = EmptyHandle; node->NextLevel = null;
if (next != null) { if (next != null) {
next->PreviousLevel = EmptyHandle; next->PreviousLevel = null;
} }
return true; return true;
} }
@@ -140,24 +137,22 @@ namespace StgSharp.HighPerformance.Memory
private bool TryRemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node) private bool TryRemoveFromBucket(int levelIndex, int sizeIndex, BucketNode* node)
{ {
int index = (3 * levelIndex) + sizeIndex; int index = (3 * levelIndex) + sizeIndex;
if ((BucketNode*) _bucketHeads[index] == node) { if (_bucketHeads[index] == node) {
return TryPopLevel(levelIndex, sizeIndex, out _); return TryPopLevel(levelIndex, sizeIndex, out _);
} }
ulong p = node->PreviousLevel; BucketNode* previous = node->PreviousLevel;
ulong n = node->NextLevel; BucketNode* next = node->NextLevel;
BucketNode* previous = (BucketNode*)p;
BucketNode* next = (BucketNode*)n;
if (previous != null) { if (previous != null) {
previous->NextLevel = n; previous->NextLevel = next;
} }
if (next != null) { if (next != null) {
next->PreviousLevel = p; next->PreviousLevel = previous;
} }
node->NextLevel = EmptyHandle; node->NextLevel = null;
node->PreviousLevel = EmptyHandle; node->PreviousLevel = null;
node->IsInBucket = false; node->IsInBucket = false;
@@ -173,10 +168,10 @@ namespace StgSharp.HighPerformance.Memory
{ {
[FieldOffset(0)] internal Entry* EntryRef; // Pointer to corresponding Entry [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(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
} }
@@ -46,7 +46,7 @@ namespace StgSharp.HighPerformance.Memory
while (cur != null) while (cur != null)
{ {
Console.WriteLine(EntryToString(cur)); Console.WriteLine(EntryToString(cur));
cur = (Entry*)cur->PreviousNear; cur = cur->PreviousNear;
if (singleStep) { if (singleStep) {
Console.ReadKey(); Console.ReadKey();
} }
@@ -63,7 +63,7 @@ namespace StgSharp.HighPerformance.Memory
while (cur != null) while (cur != null)
{ {
layout.Push(EntryToString(cur)); layout.Push(EntryToString(cur));
cur = (Entry*)cur->PreviousNear; cur = cur->PreviousNear;
} }
return layout; return layout;
} }
@@ -72,7 +72,7 @@ namespace StgSharp.HighPerformance.Memory
private static string EntryToString(Entry* e) private static string EntryToString(Entry* e)
{ {
BucketNode* b = (BucketNode*)e->Position; 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}";
} }
} }
@@ -25,6 +25,7 @@
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -50,6 +51,7 @@ namespace StgSharp.HighPerformance.Memory
/// </returns> /// </returns>
private bool AssertBackwardBoundary(ulong currentOffset, Entry* target, int level) private bool AssertBackwardBoundary(ulong currentOffset, Entry* target, int level)
{ {
level = int.Min(level, MaxLevel);
int nextLevelSize = levelSizeArray[level] * 4; int nextLevelSize = levelSizeArray[level] * 4;
ulong targetHead = target->Position - (ulong)m_Buffer; ulong targetHead = target->Position - (ulong)m_Buffer;
return (currentOffset / (ulong)nextLevelSize) == (targetHead / (ulong)nextLevelSize); return (currentOffset / (ulong)nextLevelSize) == (targetHead / (ulong)nextLevelSize);
@@ -72,6 +74,7 @@ namespace StgSharp.HighPerformance.Memory
/// </returns> /// </returns>
private bool AssertForwardBoundary(ulong currentOffset, Entry* target, int level) private bool AssertForwardBoundary(ulong currentOffset, Entry* target, int level)
{ {
level = int.Min(level, MaxLevel);
int nextLevelSize = levelSizeArray[level] * 4; int nextLevelSize = levelSizeArray[level] * 4;
ulong targetTail = target->Position - (ulong)m_Buffer + target->Size - 1; ulong targetTail = target->Position - (ulong)m_Buffer + target->Size - 1;
return (currentOffset / (ulong)nextLevelSize) == (targetTail / (ulong)nextLevelSize); return (currentOffset / (ulong)nextLevelSize) == (targetTail / (ulong)nextLevelSize);
@@ -83,6 +86,7 @@ namespace StgSharp.HighPerformance.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int DetermineSegmentIndex(uint size, int level) private int DetermineSegmentIndex(uint size, int level)
{ {
level = int.Min(level, MaxLevel);
return (int)(size - 1) / levelSizeArray[level]; return (int)(size - 1) / levelSizeArray[level];
} }
@@ -113,7 +117,7 @@ namespace StgSharp.HighPerformance.Memory
int originLevel = entry->Level; int originLevel = entry->Level;
int segment = DetermineSegmentIndex(size, originLevel); int segment = DetermineSegmentIndex(size, originLevel);
RemoveFromBucket(originLevel, segment, (BucketNode*)entry->Position); // RemoveFromBucket(originLevel, segment, (BucketNode*)entry->Position);
do do
{ {
@@ -121,8 +125,7 @@ namespace StgSharp.HighPerformance.Memory
while (true) while (true)
{ {
// backward merging - simplified to single attempt // backward merging - simplified to single attempt
ulong p = entry->PreviousNear; Entry* prev = entry->PreviousNear;
Entry* prev = (Entry*)p;
// compute offset of current block and base position // compute offset of current block and base position
ulong currentOffset = entry->Position - (ulong)m_Buffer; ulong currentOffset = entry->Position - (ulong)m_Buffer;
@@ -138,23 +141,24 @@ namespace StgSharp.HighPerformance.Memory
} }
// Update linked list // Update linked list
Entry* prevPrev = (Entry*)prev->PreviousNear; /*
Entry* prevPrev = prev->PreviousNear;
if (prevPrev != null) { if (prevPrev != null) {
prevPrev->NextNear = (ulong)entry; prevPrev->NextNear = entry;
} }
entry->PreviousNear = (ulong)prevPrev; entry->PreviousNear = prevPrev;
/**/
// Merge // Merge
entry->Position = prev->Position; entry->Position = prev->Position;
entry->Size += prev->Size; entry->Size += prev->Size;
RecycleEntry(prev); RemoveFromPositionChain(prev);
} }
while (true) while (true)
{ {
// forward merging - simplified to single attempt // forward merging - simplified to single attempt
ulong n = entry->NextNear; Entry* next = entry->NextNear;
Entry* next = (Entry*)n;
ulong currentOffset = entry->Position - (ulong)m_Buffer; ulong currentOffset = entry->Position - (ulong)m_Buffer;
@@ -169,15 +173,17 @@ namespace StgSharp.HighPerformance.Memory
} }
// Update linked list // Update linked list
Entry* nextNext = (Entry*)next->NextNear; /*
Entry* nextNext = next->NextNear;
if (nextNext != null) { if (nextNext != null) {
nextNext->PreviousNear = (ulong)entry; nextNext->PreviousNear = entry;
} }
entry->NextNear = (ulong)nextNext; entry->NextNear = nextNext;
/**/
// Merge // Merge
entry->Size += next->Size; entry->Size += next->Size;
RecycleEntry(next); RemoveFromPositionChain(next);
} }
entry->Level = GetLevelFromSize(entry->Size); entry->Level = GetLevelFromSize(entry->Size);
} while (originLevel < entry->Level); } while (originLevel < entry->Level);
@@ -189,8 +195,10 @@ namespace StgSharp.HighPerformance.Memory
return; return;
} }
entry->PreviousNear = EmptyHandle; entry->PreviousNear = null;
entry->NextNear = EmptyHandle; entry->NextNear = null;
// Console.WriteLine("entry recycled.");
_entries.Free((nuint)entry); _entries.Free((nuint)entry);
} }
@@ -199,8 +207,8 @@ namespace StgSharp.HighPerformance.Memory
/// </summary> /// </summary>
private void RemoveFromPositionChain(Entry* entry) private void RemoveFromPositionChain(Entry* entry)
{ {
Entry* prev = (Entry*)entry->PreviousNear; Entry* prev = entry->PreviousNear;
Entry* next = (Entry*)entry->NextNear; Entry* next = entry->NextNear;
if (prev != null) { if (prev != null) {
prev->NextNear = entry->NextNear; prev->NextNear = entry->NextNear;
@@ -210,8 +218,10 @@ namespace StgSharp.HighPerformance.Memory
} }
// Clear node pointers // Clear node pointers
entry->NextNear = EmptyHandle; entry->NextNear = null;
entry->PreviousNear = EmptyHandle; entry->PreviousNear = null;
// Console.WriteLine("entry recycled.");
_entries.Free((nuint)entry); _entries.Free((nuint)entry);
} }
@@ -223,11 +233,11 @@ namespace StgSharp.HighPerformance.Memory
internal struct Entry 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(28)] internal int Level; // Level of the block in the allocator
[FieldOffset(24)] internal uint Size; // Block size information [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(32)] public EntryState State;
[FieldOffset(0)] public nuint Position; // Memory block position [FieldOffset(0)] public nuint Position; // Memory block position
@@ -246,7 +256,7 @@ namespace StgSharp.HighPerformance.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsNullOrEmptyEntryIndex(ulong index) private static bool IsNullOrEmptyEntryIndex(ulong index)
{ {
return index == EmptyHandle; return index == 0;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -27,6 +27,7 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
using System; using System;
using System.Buffers; using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@@ -35,10 +36,8 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator : IDisposable public unsafe partial class HybridLayerSegregatedFitAllocator : IDisposable
{ {
private const nuint EmptyHandle = 0;
// Bucket system field - directly in main allocator class // Bucket system field - directly in main allocator class
private ulong[] _bucketHeads; private BucketNode*[] _bucketHeads;
private Entry* _spareMemory; private Entry* _spareMemory;
private readonly byte* m_Buffer; private readonly byte* m_Buffer;
@@ -57,12 +56,12 @@ namespace StgSharp.HighPerformance.Memory
m_Buffer = (byte*)NativeMemory.AlignedAlloc(byteSize, 16); m_Buffer = (byte*)NativeMemory.AlignedAlloc(byteSize, 16);
_align = 16; _align = 16;
_bucketHeads = new ulong[levelSizeArray.Length * 3]; _bucketHeads = new BucketNode*[levelSizeArray.Length * 3 + 1];
_spareMemory = (Entry*)_entries.Allocate(); _spareMemory = (Entry*)_entries.Allocate();
_spareMemory->State = EntryState.Empty; _spareMemory->State = EntryState.Empty;
_spareMemory->PreviousNear = EmptyHandle; _spareMemory->PreviousNear = null;
_spareMemory->NextNear = EmptyHandle; _spareMemory->NextNear = null;
_spareMemory->Position = (nuint)m_Buffer; _spareMemory->Position = (nuint)m_Buffer;
_spareMemory->Size = (uint)byteSize; _spareMemory->Size = (uint)byteSize;
} }
@@ -78,12 +77,12 @@ namespace StgSharp.HighPerformance.Memory
_align = align; _align = align;
_size = byteSize; _size = byteSize;
_bucketHeads = new ulong[levelSizeArray.Length * 3]; _bucketHeads = new BucketNode*[levelSizeArray.Length * 3];
_spareMemory = (Entry*)_entries.Allocate(); _spareMemory = (Entry*)_entries.Allocate();
_spareMemory->State = EntryState.Empty; _spareMemory->State = EntryState.Empty;
_spareMemory->PreviousNear = EmptyHandle; _spareMemory->PreviousNear = null;
_spareMemory->NextNear = EmptyHandle; _spareMemory->NextNear = null;
_spareMemory->Position = (nuint)m_Buffer; _spareMemory->Position = (nuint)m_Buffer;
_spareMemory->Size = (uint)byteSize; _spareMemory->Size = (uint)byteSize;
} }
+15 -1
View File
@@ -14,7 +14,7 @@
<AnalysisLevel>preview-all</AnalysisLevel> <AnalysisLevel>preview-all</AnalysisLevel>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Configurations>Debug;Release;</Configurations> <Configurations>Debug;Release;PerformanceDebug</Configurations>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -60,6 +60,13 @@
<Optimize>True</Optimize> <Optimize>True</Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
<DebugType>none</DebugType>
<NoWarn>1701;1702;0649;1591;0169</NoWarn>
<Deterministic>False</Deterministic>
<Optimize>True</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<NoWarn>1701;1702;0649;1591;0169</NoWarn> <NoWarn>1701;1702;0649;1591;0169</NoWarn>
@@ -67,6 +74,13 @@
<Optimize>True</Optimize> <Optimize>True</Optimize>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|ARM64'">
<DebugType>none</DebugType>
<NoWarn>1701;1702;0649;1591;0169</NoWarn>
<Deterministic>False</Deterministic>
<Optimize>True</Optimize>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows> <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX> <IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
@@ -7,6 +7,7 @@
<LangVersion>Preview</LangVersion> <LangVersion>Preview</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks> <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<Platforms>x64;ARM64</Platforms> <Platforms>x64;ARM64</Platforms>
<Configurations>Debug;Release;PerformanceDebug</Configurations>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+1
View File
@@ -10,6 +10,7 @@
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<Deterministic>False</Deterministic> <Deterministic>False</Deterministic>
<GenerateDocumentationFile>True</GenerateDocumentationFile> <GenerateDocumentationFile>True</GenerateDocumentationFile>
<Configurations>Debug;Release;PerformanceDebug</Configurations>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+44
View File
@@ -5,6 +5,10 @@
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="PerformanceDebug|x64">
<Configuration>PerformanceDebug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
@@ -33,6 +37,13 @@
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
@@ -44,6 +55,9 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)build</OutDir> <OutDir>$(SolutionDir)build</OutDir>
@@ -52,6 +66,10 @@
<OutDir>$(SolutionDir)build</OutDir> <OutDir>$(SolutionDir)build</OutDir>
<GenerateManifest>false</GenerateManifest> <GenerateManifest>false</GenerateManifest>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
<OutDir>$(SolutionDir)build</OutDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@@ -103,6 +121,32 @@
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AssemblerOutput>All</AssemblerOutput>
<LanguageStandard>Default</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<ShowProgress>LinkVerbose</ShowProgress>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="sn-src\k_basicop.c" /> <ClCompile Include="sn-src\k_basicop.c" />
<ClCompile Include="sn-src\dllmain.c" /> <ClCompile Include="sn-src\dllmain.c" />
+1
View File
@@ -6,6 +6,7 @@
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks> <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Configurations>Debug;Release;PerformanceDebug</Configurations>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -14,12 +14,17 @@
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<SatelliteResourceLanguages>none</SatelliteResourceLanguages> <SatelliteResourceLanguages>none</SatelliteResourceLanguages>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Configurations>Debug;Release;PerformanceDebug</Configurations>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<GenerateAssemblyInfo>False</GenerateAssemblyInfo> <GenerateAssemblyInfo>False</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<GenerateAssemblyInfo>True</GenerateAssemblyInfo> <GenerateAssemblyInfo>True</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
@@ -28,6 +33,10 @@
<GenerateAssemblyInfo>False</GenerateAssemblyInfo> <GenerateAssemblyInfo>False</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|ARM64'">
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<GenerateAssemblyInfo>True</GenerateAssemblyInfo> <GenerateAssemblyInfo>True</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
+11 -1
View File
@@ -17,7 +17,7 @@
<IncludeSymbols>False</IncludeSymbols> <IncludeSymbols>False</IncludeSymbols>
<Platforms>x64;ARM64</Platforms> <Platforms>x64;ARM64</Platforms>
<RunPostBuildEvent>Always</RunPostBuildEvent> <RunPostBuildEvent>Always</RunPostBuildEvent>
<Configurations>Debug;Release;</Configurations> <Configurations>Debug;Release;PerformanceDebug</Configurations>
</PropertyGroup> </PropertyGroup>
@@ -37,11 +37,21 @@
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Optimize>True</Optimize> <Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|ARM64'">
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows> <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX> <IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
+31
View File
@@ -34,6 +34,8 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64 Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
PerformanceDebug|ARM64 = PerformanceDebug|ARM64
PerformanceDebug|x64 = PerformanceDebug|x64
Release|ARM64 = Release|ARM64 Release|ARM64 = Release|ARM64
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
@@ -42,6 +44,10 @@ Global
{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Debug|ARM64.Build.0 = Debug|ARM64 {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.ActiveCfg = Debug|x64
{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Debug|x64.Build.0 = 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.ActiveCfg = Release|ARM64
{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Release|ARM64.Build.0 = Release|ARM64 {3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Release|ARM64.Build.0 = Release|ARM64
{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}.Release|x64.ActiveCfg = Release|x64 {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|ARM64.Build.0 = Debug|ARM64
{610B992B-BB34-49C3-9993-676C595FC12E}.Debug|x64.ActiveCfg = Debug|x64 {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}.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.ActiveCfg = Release|ARM64
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.Build.0 = Release|ARM64 {610B992B-BB34-49C3-9993-676C595FC12E}.Release|ARM64.Build.0 = Release|ARM64
{610B992B-BB34-49C3-9993-676C595FC12E}.Release|x64.ActiveCfg = Release|x64 {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|ARM64.Build.0 = Debug|ARM64
{20CBFF26-6746-402E-992C-7B643E9423EB}.Debug|x64.ActiveCfg = Debug|x64 {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}.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.ActiveCfg = Release|ARM64
{20CBFF26-6746-402E-992C-7B643E9423EB}.Release|ARM64.Build.0 = Release|ARM64 {20CBFF26-6746-402E-992C-7B643E9423EB}.Release|ARM64.Build.0 = Release|ARM64
{20CBFF26-6746-402E-992C-7B643E9423EB}.Release|x64.ActiveCfg = Release|x64 {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|ARM64.Build.0 = Debug|ARM64
{10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Debug|x64.ActiveCfg = Debug|x64 {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}.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.ActiveCfg = Release|x64
{10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Release|ARM64.Build.0 = Release|x64 {10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Release|ARM64.Build.0 = Release|x64
{10B5819F-2A62-41B6-980A-EB9E76A0E95C}.Release|x64.ActiveCfg = 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|ARM64.Build.0 = Debug|ARM64
{5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Debug|x64.ActiveCfg = Debug|x64 {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}.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.ActiveCfg = Release|x64
{5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Release|ARM64.Build.0 = Release|x64 {5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Release|ARM64.Build.0 = Release|x64
{5B51F5EA-138C-46B5-B36F-1D389968B6CF}.Release|x64.ActiveCfg = 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|ARM64.Build.0 = Debug|x64
{D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Debug|x64.ActiveCfg = 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}.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.ActiveCfg = Release|ARM64
{D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Release|ARM64.Build.0 = Release|ARM64 {D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Release|ARM64.Build.0 = Release|ARM64
{D9538DE0-EE4C-4183-86D6-7DFC08A7BDFB}.Release|x64.ActiveCfg = Release|x64 {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|ARM64.Build.0 = Debug|ARM64
{9946599F-4D34-440F-840D-F9443D5AEFAA}.Debug|x64.ActiveCfg = Debug|x64 {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}.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.ActiveCfg = Release|ARM64
{9946599F-4D34-440F-840D-F9443D5AEFAA}.Release|ARM64.Build.0 = 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.ActiveCfg = Release|x64
{9946599F-4D34-440F-840D-F9443D5AEFAA}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE