hlsf wrong slicing solving
This commit is contained in:
@@ -47,12 +47,18 @@ namespace StgSharp.HighPerformance.Memory
|
||||
EntryHandle = handle;
|
||||
Pointer = (byte*)handle->Position;
|
||||
AllocSize = s;
|
||||
|
||||
// Console.WriteLine($"{(ulong)handle->PreviousNear}<->{(ulong)handle->NextNear},\t{handle->Size}");
|
||||
}
|
||||
|
||||
public readonly ref byte this[int index]
|
||||
public readonly ref byte this[uint index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => ref Pointer[index];
|
||||
get
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>(index, AllocSize);
|
||||
return ref Pointer[index];
|
||||
}
|
||||
}
|
||||
|
||||
public readonly byte* Pointer { get; init; }
|
||||
@@ -73,7 +79,7 @@ namespace StgSharp.HighPerformance.Memory
|
||||
|
||||
private HybridLayerSegregatedFitAllocationHandle _handle;
|
||||
|
||||
private int _index = -1;
|
||||
private uint _index = ~0u;
|
||||
|
||||
internal Enumerator(HybridLayerSegregatedFitAllocationHandle span)
|
||||
{
|
||||
|
||||
@@ -25,18 +25,8 @@
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
using Microsoft.Win32;
|
||||
|
||||
using StgSharp.Threading;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using hlsfHandle = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
|
||||
|
||||
@@ -121,13 +111,15 @@ namespace StgSharp.HighPerformance.Memory
|
||||
current->NextNear = newEntry;
|
||||
next->PreviousNear = newEntry;
|
||||
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, Math.Min(blockCount - 1, 2), bucket);
|
||||
|
||||
// set new entry
|
||||
// Entry* old = current;
|
||||
current = newEntry;
|
||||
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, Math.Min(blockCount - 1, 2), bucket);
|
||||
|
||||
// Console.WriteLine($"{(ulong)current->PreviousNear}<->{(ulong)current->NextNear},\t{current->Size}");
|
||||
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= (ulong)s;
|
||||
if (remainSize <= (ulong)levelSize)
|
||||
@@ -212,6 +204,8 @@ namespace StgSharp.HighPerformance.Memory
|
||||
// Entry* old = current;
|
||||
current = newEntry;
|
||||
|
||||
// Console.WriteLine($"{(ulong)current->PreviousNear}<->{(ulong)current->NextNear},\t{current->Size}");
|
||||
|
||||
// update lock and data
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= (ulong)s;
|
||||
@@ -225,6 +219,8 @@ namespace StgSharp.HighPerformance.Memory
|
||||
{
|
||||
e->Size = (uint)(offset);
|
||||
e->Level = GetLevelFromSize((uint)offset);
|
||||
|
||||
// Console.WriteLine("Alloc ok");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +237,6 @@ namespace StgSharp.HighPerformance.Memory
|
||||
{
|
||||
nuint pos = _spareMemory->Position;
|
||||
nuint blockSize = (nuint)levelSizeArray[^1] * 2; // Use last level size (16MB)
|
||||
nuint newPos = pos + blockSize;
|
||||
|
||||
Entry* previous;
|
||||
previous = _spareMemory->PreviousNear;
|
||||
@@ -250,6 +245,7 @@ namespace StgSharp.HighPerformance.Memory
|
||||
handle = null;
|
||||
return false; // No spare memory available
|
||||
}
|
||||
nuint newPos = pos + blockSize;
|
||||
|
||||
// Check if we have enough space
|
||||
if (newPos > ((nuint)m_Buffer) + _size)
|
||||
@@ -270,8 +266,6 @@ namespace StgSharp.HighPerformance.Memory
|
||||
BucketNode* b = (BucketNode*)handle->Position;
|
||||
b->EntryRef = handle;
|
||||
|
||||
// PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
|
||||
|
||||
// update position linked list
|
||||
handle->NextNear = _spareMemory;
|
||||
handle->PreviousNear = previous;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -155,7 +156,7 @@ namespace StgSharp.HighPerformance.Memory
|
||||
node->NextLevel = null;
|
||||
node->PreviousLevel = null;
|
||||
node->IsInBucket = false;
|
||||
|
||||
node->EntryRef = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,15 @@ namespace StgSharp.HighPerformance.Memory
|
||||
/// </summary>
|
||||
private void MergeAndRemoveFromBuckets(Entry* entry)
|
||||
{
|
||||
if (entry == null) {
|
||||
// TODO
|
||||
/*
|
||||
* 1.有限回收,最多向上收集2层(算上当前总共3层)
|
||||
* 2.单层内就可以通过前后链表遍历解决,很容易做到
|
||||
* 3.由于SLAB分配器内部包含快速复用路径,因而可以考虑直接进行Free掉被合并的Entry。复用成本很低(因为SLAB既没有Version也没有IEnumerable,所以不会有额外的操作计数损耗)
|
||||
* 4.后续提供HLSF.Collect全量整理API,从头遍历邻接块进行彻底的合并
|
||||
*/
|
||||
if (entry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -130,14 +138,16 @@ namespace StgSharp.HighPerformance.Memory
|
||||
// compute offset of current block and base position
|
||||
ulong currentOffset = entry->Position - (ulong)m_Buffer;
|
||||
|
||||
if (prev == null ||
|
||||
prev == _spareMemory ||
|
||||
!AssertBackwardBoundary(currentOffset, prev, originLevel) ||
|
||||
!IsAdjacentTo(entry, prev) ||
|
||||
entry->Level != prev->Level ||
|
||||
!TryRemoveFromBucket(originLevel, DetermineSegmentIndex(prev->Size, originLevel), (BucketNode*)prev->Position))
|
||||
if (prev != null &&
|
||||
prev != _spareMemory &&
|
||||
AssertBackwardBoundary(currentOffset, prev, originLevel) &&
|
||||
IsAdjacentTo(entry, prev) &&
|
||||
TryRemoveFromBucket(originLevel, DetermineSegmentIndex(prev->Size, originLevel), (BucketNode*)prev->Position))
|
||||
{
|
||||
break;
|
||||
// Merge
|
||||
entry->Position = prev->Position;
|
||||
entry->Size += prev->Size;
|
||||
RemoveFromPositionChain(prev);
|
||||
}
|
||||
|
||||
// Update linked list
|
||||
@@ -148,11 +158,6 @@ namespace StgSharp.HighPerformance.Memory
|
||||
}
|
||||
entry->PreviousNear = prevPrev;
|
||||
/**/
|
||||
|
||||
// Merge
|
||||
entry->Position = prev->Position;
|
||||
entry->Size += prev->Size;
|
||||
RemoveFromPositionChain(prev);
|
||||
}
|
||||
|
||||
while (true)
|
||||
@@ -189,19 +194,6 @@ namespace StgSharp.HighPerformance.Memory
|
||||
} while (originLevel < entry->Level);
|
||||
}
|
||||
|
||||
private void RecycleEntry(Entry* entry)
|
||||
{
|
||||
if (entry is null) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry->PreviousNear = null;
|
||||
entry->NextNear = null;
|
||||
|
||||
// Console.WriteLine("entry recycled.");
|
||||
_entries.Free((nuint)entry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove node from position linked list
|
||||
/// </summary>
|
||||
@@ -246,6 +238,7 @@ namespace StgSharp.HighPerformance.Memory
|
||||
internal enum EntryState : uint
|
||||
{
|
||||
|
||||
Spare,
|
||||
Empty,
|
||||
Allocated
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace StgSharp.HighPerformance.Memory
|
||||
_bucketHeads = new BucketNode*[levelSizeArray.Length * 3 + 1];
|
||||
|
||||
_spareMemory = (Entry*)_entries.Allocate();
|
||||
_spareMemory->State = EntryState.Empty;
|
||||
_spareMemory->State = EntryState.Spare;
|
||||
_spareMemory->PreviousNear = null;
|
||||
_spareMemory->NextNear = null;
|
||||
_spareMemory->Position = (nuint)m_Buffer;
|
||||
|
||||
Reference in New Issue
Block a user