hlsf wrong slicing solving

This commit is contained in:
Youmu Liu
2025-11-26 20:52:12 +08:00
parent 23914f05ac
commit 83537c7be7
9 changed files with 108 additions and 172 deletions
@@ -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;