Merge from main branch.
This commit is contained in:
Youmu Liu
2026-04-20 13:31:40 +08:00
14 changed files with 421 additions and 532 deletions
+29 -41
View File
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="HlsfAllocatorBench" // file="HlsfAllocatorBench.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -42,17 +45,9 @@ namespace StgSharp.Benchmark
private const int AllocationCount = 2048; private const int AllocationCount = 2048;
private static readonly int[] AllocSizes = [ private static readonly int[] AllocSizes = [ 64, 96, 150, 200, 400, 1024, 4096 ];
64,
96,
150,
200,
400,
1024,
4096
];
private HybridLayerSegregatedFitAllocator _hlsfAllocator = null!; private HybridLayerSegregatedFitAllocator _hlsfAllocator = null!;
private readonly List<HybridLayerSegregatedFitAllocationHandle> _hlsfLocalList = new(); private readonly List<hlsfHandle> _hlsfLocalList = new();
private readonly List<nint> _libcLocalList = new(); private readonly List<nint> _libcLocalList = new();
private Random _random = new(42); private Random _random = new(42);
@@ -106,9 +101,7 @@ namespace StgSharp.Benchmark
_hlsfAllocator = new HybridLayerSegregatedFitAllocator(GetArenaBytes(), align:(int)Alignment); _hlsfAllocator = new HybridLayerSegregatedFitAllocator(GetArenaBytes(), align:(int)Alignment);
} }
private static uint AlignSize( private static uint AlignSize(uint size)
uint size
)
{ {
uint mask = Alignment - 1; uint mask = Alignment - 1;
return (size + mask) & ~mask; return (size + mask) & ~mask;
@@ -121,9 +114,7 @@ namespace StgSharp.Benchmark
int mb = defaultMb; int mb = defaultMb;
string? env = Environment.GetEnvironmentVariable("HLSF_BENCH_ARENA_MB"); string? env = Environment.GetEnvironmentVariable("HLSF_BENCH_ARENA_MB");
if (!string.IsNullOrWhiteSpace(env) && if (!string.IsNullOrWhiteSpace(env) && int.TryParse(env, out int parsed) && parsed >= minMb) {
int.TryParse(env, out int parsed) &&
parsed >= minMb) {
mb = parsed; mb = parsed;
} }
@@ -132,17 +123,14 @@ namespace StgSharp.Benchmark
private uint GetNextRandomSize() => (uint)AllocSizes[_random.Next(AllocSizes.Length)]; private uint GetNextRandomSize() => (uint)AllocSizes[_random.Next(AllocSizes.Length)];
private void RunHlsf( private void RunHlsf(HybridLayerSegregatedFitAllocator allocator, FreePolicy policy)
HybridLayerSegregatedFitAllocator allocator,
FreePolicy policy
)
{ {
_hlsfLocalList.Clear(); _hlsfLocalList.Clear();
for (int i = 0; i < AllocationCount; i++) for (int i = 0; i < AllocationCount; i++)
{ {
uint size = AlignSize(GetNextRandomSize()); uint size = AlignSize(GetNextRandomSize());
HybridLayerSegregatedFitAllocationHandle allocate = allocator.Alloc(size); hlsfHandle allocate = allocator.Alloc(size);
_hlsfLocalList.Add(allocate); _hlsfLocalList.Add(allocate);
} }
+44 -62
View File
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="SwissTable" // file="SwissTable.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -46,16 +49,13 @@ namespace StgSharp.Collections
private const int EntryMaskWidth = 10; // 1024 entries total, 16 per bucket private const int EntryMaskWidth = 10; // 1024 entries total, 16 per bucket
public const int MaxCapacity = BucketCount * BucketSize; // 256 entries per bucket, 1024 buckets public const int MaxCapacity = BucketCount * BucketSize; // 256 entries per bucket, 1024 buckets
public static readonly int RequestedNativeMemorySize = Unsafe.SizeOf<Entry>(); public static readonly nuint RequestedNativeMemorySize = (nuint)Unsafe.SizeOf<Entry>();
private readonly Entry* _entries; private readonly Entry* _entries;
private readonly Action<nuint> _freeHandle; private readonly Action<nuint> _freeHandle;
private bool _disposed; private bool _disposed;
private SwissTable( private SwissTable(Entry* buffer, Action<nuint> freeHandle)
Entry* buffer,
Action<nuint> freeHandle
)
{ {
_entries = buffer; _entries = buffer;
_freeHandle = freeHandle; _freeHandle = freeHandle;
@@ -72,6 +72,17 @@ namespace StgSharp.Collections
return new SwissTable(buffer, handle => NativeMemory.AlignedFree((void*)handle)); return new SwissTable(buffer, handle => NativeMemory.AlignedFree((void*)handle));
} }
public static SwissTable Create(Func<nuint, nuint> allocator, Action<nuint> freeHandle)
{
Entry* buffer = (Entry*)allocator(RequestedNativeMemorySize);
for (int i = 0; i < BucketCount; i++)
{
// Set all control bytes to 0xFF (empty)
Unsafe.InitBlock(&(*buffer)[i].Control, 0xFF, BucketSize);
}
return new SwissTable(buffer, freeHandle);
}
public void Dispose() public void Dispose()
{ {
if (_disposed) { if (_disposed) {
@@ -82,11 +93,7 @@ namespace StgSharp.Collections
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
public bool TryAddOrSet( public bool TryAddOrSet(nuint key, nuint value, out bool isNewKey)
nuint key,
nuint value,
out bool isNewKey
)
{ {
uint hash = BitOperations.Crc32C(CrcMagic, (ulong)key); uint hash = BitOperations.Crc32C(CrcMagic, (ulong)key);
ushort entry = (ushort)(hash & (BucketCount - 1)); ushort entry = (ushort)(hash & (BucketCount - 1));
@@ -94,10 +101,7 @@ namespace StgSharp.Collections
return IBucketScanner.Current.TrySet(key, hash, bucket, value, out isNewKey); return IBucketScanner.Current.TrySet(key, hash, bucket, value, out isNewKey);
} }
public bool TryGet( public bool TryGet(nuint key, out nuint value)
nuint key,
out nuint value
)
{ {
uint hash = BitOperations.Crc32C(CrcMagic, key); uint hash = BitOperations.Crc32C(CrcMagic, key);
ushort entry = (ushort)(hash & (BucketCount - 1)); ushort entry = (ushort)(hash & (BucketCount - 1));
@@ -112,21 +116,15 @@ namespace StgSharp.Collections
*/ */
} }
public bool TryRemove( public bool TryRemove(nuint key, out nuint value)
nuint key,
out nuint value
)
{ {
uint hash = BitOperations.Crc32C(CrcMagic, (ulong)key); uint hash = BitOperations.Crc32C(CrcMagic, key);
ushort entry = (ushort)(hash & (BucketCount - 1)); ushort entry = (ushort)(hash & (BucketCount - 1));
Bucket* bucket = &(*_entries)[entry]; Bucket* bucket = &(*_entries)[entry];
return IBucketScanner.Current.TryRemove(key, hash, bucket, out value); return IBucketScanner.Current.TryRemove(key, hash, bucket, out value);
} }
internal static SwissTable Create( internal static SwissTable Create(nuint bufferPtr, Action<nuint> FreeHandle)
nuint bufferPtr,
Action<nuint> FreeHandle
)
{ {
Entry* buffer = (Entry*)bufferPtr; Entry* buffer = (Entry*)bufferPtr;
for (int i = 0; i < BucketCount; i++) for (int i = 0; i < BucketCount; i++)
@@ -164,27 +162,11 @@ namespace StgSharp.Collections
static IBucketScanner Current { get; } = Create(); static IBucketScanner Current { get; } = Create();
bool TryFind( bool TryFind(nuint key, uint Hash, Bucket* bucket, out nuint value);
nuint key,
uint Hash,
Bucket* bucket,
out nuint value
);
unsafe bool TryRemove( unsafe bool TryRemove(nuint key, uint hash, Bucket* bucket, out nuint value);
nuint key,
uint hash,
Bucket* bucket,
out nuint value
);
bool TrySet( bool TrySet(nuint key, uint hash, Bucket* bucket, nuint value, out bool isNewKey);
nuint key,
uint hash,
Bucket* bucket,
nuint value,
out bool isNewKey
);
private static IBucketScanner Create() private static IBucketScanner Create()
{ {
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="HLSFAllocationHandle" // file="HLSFAllocationHandle.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload Space // AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -36,13 +39,13 @@ using Allocator = StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocator;
namespace StgSharp.Mathematics.Memory namespace StgSharp.Mathematics.Memory
{ {
public readonly unsafe struct HybridLayerSegregatedFitAllocationHandle public readonly unsafe struct hlsfHandle
{ {
internal readonly Allocator.Entry* EntryHandle; internal readonly Allocator.Entry* EntryHandle;
public readonly long AllocSize; public readonly long AllocSize;
internal HybridLayerSegregatedFitAllocationHandle(Allocator.Entry* handle, long s) internal hlsfHandle(Allocator.Entry* handle, long s)
{ {
EntryHandle = handle; EntryHandle = handle;
Pointer = (byte*)handle->Position; Pointer = (byte*)handle->Position;
@@ -77,11 +80,11 @@ namespace StgSharp.Mathematics.Memory
public ref struct Enumerator : IEnumerator<byte> public ref struct Enumerator : IEnumerator<byte>
{ {
private HybridLayerSegregatedFitAllocationHandle _handle; private hlsfHandle _handle;
private uint _index = ~0u; private uint _index = ~0u;
internal Enumerator(HybridLayerSegregatedFitAllocationHandle span) internal Enumerator(hlsfHandle span)
{ {
_handle = span; _handle = span;
Span = span.BufferHandle; Span = span.BufferHandle;
@@ -1,42 +1,43 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="HLSFAllocator.Alloc" // file="HLSFAllocator.Alloc.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
using System; using System;
using System.Numerics; using System.Numerics;
using hlsfHandle = StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocationHandle; using hlsfHandle = StgSharp.Mathematics.Memory.hlsfHandle;
namespace StgSharp.Mathematics.Memory namespace StgSharp.Mathematics.Memory
{ {
public unsafe partial class HybridLayerSegregatedFitAllocator public unsafe partial class HybridLayerSegregatedFitAllocator
{ {
public partial hlsfHandle Alloc( public partial hlsfHandle Alloc(long size)
long size
)
{ {
if (size > _maxSize) { if (size > _maxSize) {
throw new InvalidOperationException("Requested size exceeds maximum allocatable size."); throw new InvalidOperationException("Requested size exceeds maximum allocatable size.");
@@ -93,10 +94,7 @@ namespace StgSharp.Mathematics.Memory
/// <param name="sizeToSlice"> /// <param name="sizeToSlice">
/// ///
/// </param> /// </param>
private void SliceMemory( private void SliceMemory(Entry* e, long sizeToSlice)
Entry* e,
long sizeToSlice
)
{ {
Entry* next = e; Entry* next = e;
long remain = sizeToSlice; // remained size to slice long remain = sizeToSlice; // remained size to slice
@@ -194,9 +192,7 @@ namespace StgSharp.Mathematics.Memory
/// <returns> /// <returns>
/// True if allocation succeeded /// True if allocation succeeded
/// </returns> /// </returns>
private bool TryAllocateNew32MBBlock( private bool TryAllocateNew32MBBlock(out Entry* handle)
out Entry* handle
)
{ {
nuint pos = _spareMemory->Position; nuint pos = _spareMemory->Position;
long remain = _spareMemory->Size; long remain = _spareMemory->Size;
@@ -226,11 +222,7 @@ namespace StgSharp.Mathematics.Memory
/// <summary> /// <summary>
/// Helper method for allocation - converts BucketNode to Entry /// Helper method for allocation - converts BucketNode to Entry
/// </summary> /// </summary>
private bool TryPopLevelForAllocation( private bool TryPopLevelForAllocation(int levelIndex, int sizeIndex, out Entry* entry)
int levelIndex,
int sizeIndex,
out Entry* entry
)
{ {
if (TryPopLevel(levelIndex, sizeIndex, out BucketNode* bucketNode)) if (TryPopLevel(levelIndex, sizeIndex, out BucketNode* bucketNode))
{ {
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="HLSFAllocator.Free" // file="HLSFAllocator.Free.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -35,7 +38,7 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using hlsfHandle = StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocationHandle; using hlsfHandle = StgSharp.Mathematics.Memory.hlsfHandle;
namespace StgSharp.Mathematics.Memory namespace StgSharp.Mathematics.Memory
{ {
@@ -90,10 +93,7 @@ namespace StgSharp.Mathematics.Memory
/// Handle to the allocated memory block /// Handle to the allocated memory block
/// <param name="collectPolicy"> /// <param name="collectPolicy">
/// </param> /// </param>
public void Free( public void Free(hlsfHandle handle, FreePolicy collectPolicy = FreePolicy.NoCollect)
hlsfHandle handle,
FreePolicy collectPolicy = FreePolicy.NoCollect
)
{ {
Entry* e = handle.EntryHandle; Entry* e = handle.EntryHandle;
if (e == null) { if (e == null) {
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="HLSFAllocator" // file="HLSFAllocator.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -30,7 +33,7 @@ using System.Buffers;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using hlsfHandle = StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocationHandle; using hlsfHandle = StgSharp.Mathematics.Memory.hlsfHandle;
namespace StgSharp.Mathematics.Memory namespace StgSharp.Mathematics.Memory
{ {
@@ -43,47 +46,41 @@ namespace StgSharp.Mathematics.Memory
// _spareMemory is also the beginning position of allocator // _spareMemory is also the beginning position of allocator
private Entry *_spareMemory; private Entry *_spareMemory;
private readonly byte* m_Buffer; private readonly byte* m_Buffer;
private readonly Action<nuint> _freeHandle;
private bool disposedValue; private bool disposedValue;
private readonly int _align; private readonly int _align;
private readonly long _maxSize; private readonly long _maxSize;
private readonly nuint _size; private readonly nuint _size;
private readonly SlabAllocator<Entry> _entries; private readonly SlabAllocator<Entry> _entries;
public HybridLayerSegregatedFitAllocator( internal HybridLayerSegregatedFitAllocator(
nuint byteSize nuint byteSize,
) int align,
long maxBlockSize,
Func<nuint, int, nuint> allocator,
Action<nuint> freeHandle,
SlabAllocator<Entry>? entryManager)
: this(byteSize, align, maxBlockSize, (void*)allocator(byteSize, align), freeHandle, entryManager) { }
internal HybridLayerSegregatedFitAllocator(
nuint byteSize,
int align,
long maxBlockSize,
void* externalPointer,
Action<nuint> freeHandle,
SlabAllocator<Entry>? entryManager = null)
{ {
if (byteSize < 64) { if (align < 16 || (align & (align - 1)) != 0) {
throw new InvalidOperationException(); throw new ArgumentException(
"Alignment must be a power of two and at least 16 bytes.");
} }
_entries = SlabAllocator.Create<Entry>(64, SlabBufferLayout.Chunked, false); _entries = entryManager ?? SlabAllocator.Create<Entry>(64, SlabBufferLayout.Chunked, false);
_size = byteSize; m_Buffer = (byte*)externalPointer;
m_Buffer = (byte *)NativeMemory.AlignedAlloc(byteSize, 16); _align = align;
_align = 16;
_bucketHeads = new BucketNode*[_levelSizeArray.Length * 3 + 1];
_spareMemory = (Entry *)_entries.Allocate();
_spareMemory->State = EntryState.Spare;
_spareMemory->PreviousNear = _spareMemory;
_spareMemory->NextNear = _spareMemory;
_spareMemory->Position = (nuint)m_Buffer;
_spareMemory->Size = (long)byteSize;
_maxSize = 32U * 1024U * 1024U;
}
public HybridLayerSegregatedFitAllocator(
nuint byteSize,
uint maxBlockSize
)
{
_entries = SlabAllocator.Create<Entry>(64, SlabBufferLayout.Chunked, false);
m_Buffer = (byte *)NativeMemory.AlignedAlloc(byteSize, 16);
_align = 16;
_size = byteSize; _size = byteSize;
_spareMemory = (Entry *)_entries.Allocate(); _spareMemory = (Entry*)_entries.Allocate();
_spareMemory->State = EntryState.Empty; _spareMemory->State = EntryState.Empty;
_spareMemory->PreviousNear = _spareMemory; _spareMemory->PreviousNear = _spareMemory;
_spareMemory->NextNear = _spareMemory; _spareMemory->NextNear = _spareMemory;
@@ -93,7 +90,7 @@ namespace StgSharp.Mathematics.Memory
int levelCountOrigin = _levelSizeArray.Length; int levelCountOrigin = _levelSizeArray.Length;
int levelCount = GetLevelFromSize(maxBlockSize) + 1; int levelCount = GetLevelFromSize(maxBlockSize) + 1;
Array.Resize(ref _levelSizeArray, levelCount); Array.Resize(ref _levelSizeArray, levelCount);
_bucketHeads = new BucketNode *[(levelCount * 3) + 1]; _bucketHeads = new BucketNode*[(levelCount * 3) + 1];
int size = _levelSizeArray[^1]; int size = _levelSizeArray[^1];
for (int i = levelCountOrigin; i < levelCount; i++) for (int i = levelCountOrigin; i < levelCount; i++)
{ {
@@ -101,72 +98,25 @@ namespace StgSharp.Mathematics.Memory
_levelSizeArray[i] = size; _levelSizeArray[i] = size;
} }
_maxSize = maxBlockSize; _maxSize = maxBlockSize;
_freeHandle = freeHandle ?? (static _ => { });
} }
public HybridLayerSegregatedFitAllocator( public HybridLayerSegregatedFitAllocator(nuint byteSize)
nuint byteSize, : this(
int align byteSize, 16, 32U * 1024U * 1024U, NativeMemory.AlignedAlloc(byteSize, 16), ptr => NativeMemory.AlignedFree((void*)ptr)) { }
)
{
if (align < 16 || (align & (align - 1)) != 0) {
throw new ArgumentException(
"Alignment must be a power of two and at least 16 bytes.");
}
_entries = SlabAllocator.Create<Entry>(64, SlabBufferLayout.Chunked, false);
m_Buffer = (byte *)NativeMemory.AlignedAlloc(byteSize, (nuint)align);
_align = align;
_size = byteSize;
_bucketHeads = new BucketNode *[_levelSizeArray.Length * 3 + 1]; public HybridLayerSegregatedFitAllocator(nuint byteSize, uint maxBlockSize)
: this(
byteSize, 16, maxBlockSize, NativeMemory.AlignedAlloc(byteSize, 16), ptr => NativeMemory.AlignedFree((void*)ptr)) { }
_spareMemory = (Entry *)_entries.Allocate(); public HybridLayerSegregatedFitAllocator(nuint byteSize, int align)
_spareMemory->State = EntryState.Empty; : this(
_spareMemory->PreviousNear = _spareMemory; byteSize, align, 32U * 1024U * 1024U, NativeMemory.AlignedAlloc(byteSize, 16), ptr => NativeMemory.AlignedFree((void*)ptr)) { }
_spareMemory->NextNear = _spareMemory;
_spareMemory->Position = (nuint)m_Buffer;
_spareMemory->Size = (long)byteSize;
_maxSize = 32U * 1024U * 1024U; public HybridLayerSegregatedFitAllocator(nuint byteSize, int align, long maxBlockSize)
} : this(byteSize, align, maxBlockSize, NativeMemory.AlignedAlloc(byteSize, 16), ptr => NativeMemory.AlignedFree((void*)ptr)) { }
public HybridLayerSegregatedFitAllocator( public partial hlsfHandle Alloc(long size);
nuint byteSize,
int align,
long maxBlockSize
)
{
if (align < 16 || (align & (align - 1)) != 0) {
throw new ArgumentException(
"Alignment must be a power of two and at least 16 bytes.");
}
_entries = SlabAllocator.Create<Entry>(64, SlabBufferLayout.Chunked, false);
m_Buffer = (byte*)NativeMemory.AlignedAlloc(byteSize, (nuint)align);
_align = align;
_size = byteSize;
_spareMemory = (Entry *)_entries.Allocate();
_spareMemory->State = EntryState.Empty;
_spareMemory->PreviousNear = _spareMemory;
_spareMemory->NextNear = _spareMemory;
_spareMemory->Position = (nuint)m_Buffer;
_spareMemory->Size = (long)byteSize;
int levelCountOrigin = _levelSizeArray.Length;
int levelCount = GetLevelFromSize(maxBlockSize) + 1;
Array.Resize(ref _levelSizeArray, levelCount);
_bucketHeads = new BucketNode *[levelCount * 3 + 1];
int size = _levelSizeArray[^1];
for (int i = levelCountOrigin; i < levelCount; i++)
{
size *= 4;
_levelSizeArray[i] = size;
}
_maxSize = maxBlockSize;
}
public partial hlsfHandle Alloc(
long size
);
public partial void Collect(); public partial void Collect();
@@ -176,16 +126,14 @@ namespace StgSharp.Mathematics.Memory
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose( protected virtual void Dispose(bool disposing)
bool disposing
)
{ {
if (!disposedValue) if (!disposedValue)
{ {
if (disposing) { if (disposing) {
_entries.Dispose(); _entries.Dispose();
} }
NativeMemory.AlignedFree(m_Buffer); _freeHandle((nuint)m_Buffer);
disposedValue = true; disposedValue = true;
} }
} }
+40 -47
View File
@@ -1,35 +1,41 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="L4" // file="L4.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
using StgSharp.Collections; using StgSharp.Collections;
using StgSharp.Common.HighPerformance.ProcessorAbstraction; using StgSharp.Common.HighPerformance.ProcessorAbstraction;
using StgSharp.Mathematics.Memory;
using System.Data; using System.Data;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using HLSF = StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocator;
namespace StgSharp.HighPerformance.Memory namespace StgSharp.HighPerformance.Memory
{ {
public sealed unsafe partial class L4 : IDisposable public sealed unsafe partial class L4 : IDisposable
@@ -40,13 +46,13 @@ namespace StgSharp.HighPerformance.Memory
private const int PredictionLeastAhead = 1024; private const int PredictionLeastAhead = 1024;
private static readonly IIntrinsicKernel _intrinsic = IIntrinsicKernel.Instance; private static readonly IIntrinsicKernel _intrinsic = IIntrinsicKernel.Instance;
private readonly CacheLineData* _data;
private readonly EvictionArray* _eviction; private readonly EvictionArray* _eviction;
private readonly CacheLineHead* _head; private readonly CacheLineHead* _head;
private readonly CacheLinePrediction* _prediction; private readonly CacheLinePrediction* _prediction;
private bool _disposed; private bool _disposed;
private bool _exhausted; private bool _exhausted;
private readonly HLSF _bufferAllocator;
private int _activeCount; private int _activeCount;
private int _aheadCount; private int _aheadCount;
@@ -55,20 +61,19 @@ namespace StgSharp.HighPerformance.Memory
private int _maxId; private int _maxId;
private volatile int _prefetching; private volatile int _prefetching;
private readonly nuint _baseAddress; private readonly nuint _baseAddress;
private readonly SlabAllocator<HLSF.Entry> _entryManager;
private readonly SwissTable _map; private readonly SwissTable _map;
private readonly UnmanagedStack<int> _idMux; private readonly UnmanagedStack<int> _idMux;
public L4( public L4(int bindedNuma, nuint bufferSize = 8192 * 8192, int align = 16, int maxCacheLineSize = 8192)
int bindedNuma
)
{ {
_bindedNuma = bindedNuma; _bindedNuma = bindedNuma;
// init order is fallow by align requirement of each component. // init order is fallow by align requirement of each component.
nuint cacheSize = ((nuint)Unsafe.SizeOf<CacheLineData>()) * CacheLineCount; // SIMDID, no less than 16 byte bit nuint cacheSize = ((nuint)Unsafe.SizeOf<HLSF.Entry>()) * CacheLineCount; // SIMDID, no less than 16 byte bit
nuint entrySize = ((nuint)Unsafe.SizeOf<CacheLineHead>()) * CacheLineCount; // 16 byte align nuint entrySize = ((nuint)Unsafe.SizeOf<CacheLineHead>()) * CacheLineCount; // 16 byte align
nuint predictionSize = ((nuint)Unsafe.SizeOf<CacheLinePrediction>()) * PredictionCount; //16 byte align nuint predictionSize = ((nuint)Unsafe.SizeOf<CacheLinePrediction>()) * PredictionCount; //16 byte align
nuint mapSize = (nuint)SwissTable.RequestedNativeMemorySize; // 16 byte align nuint mapSize = SwissTable.RequestedNativeMemorySize; // 16 byte align
nuint rrpvSize = (nuint)Unsafe.SizeOf<EvictionArray>(); // 16 byte align nuint rrpvSize = (nuint)Unsafe.SizeOf<EvictionArray>(); // 16 byte align
nuint stackSize = ((nuint)sizeof(int)) * CacheLineCount; // int align nuint stackSize = ((nuint)sizeof(int)) * CacheLineCount; // int align
@@ -78,8 +83,10 @@ namespace StgSharp.HighPerformance.Memory
nuint ptr = _baseAddress; nuint ptr = _baseAddress;
// init all components with the buffer, and move the buffer pointer forward. // init all components with the buffer, and move the buffer pointer forward.
_entryManager = SlabAllocator.FromBuffer();
_bufferAllocator = new HLSF(cacheSize, align, maxCacheLineSize, (void*)_baseAddress, static _ => { });
nuint _buffer = _baseAddress; nuint _buffer = _baseAddress;
_data = (CacheLineData*)_buffer;
ptr += cacheSize; ptr += cacheSize;
_head = (CacheLineHead*)ptr; _head = (CacheLineHead*)ptr;
ptr += entrySize; ptr += entrySize;
@@ -98,9 +105,7 @@ namespace StgSharp.HighPerformance.Memory
// public IL4Predict PrefetchPredict { get; set; } // public IL4Predict PrefetchPredict { get; set; }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ContinueOnce( public void ContinueOnce(L4CacheLine line)
L4CacheLine line
)
{ {
if (line.Address > 0) { if (line.Address > 0) {
_ = Interlocked.Decrement(ref _aheadCount); _ = Interlocked.Decrement(ref _aheadCount);
@@ -123,12 +128,13 @@ namespace StgSharp.HighPerformance.Memory
_disposed = true; _disposed = true;
_map.Dispose(); _map.Dispose();
_idMux.Dispose(); _idMux.Dispose();
_bufferAllocator.Dispose();
nuint cacheSize = ((nuint)Unsafe.SizeOf<CacheLineData>()) * CacheLineCount; // SIMDID, no less than 16 byte bit nuint cacheSize = ((nuint)Unsafe.SizeOf<CacheLineData>()) * CacheLineCount; // SIMDID, no less than 16 byte bit
nuint entrySize = ((nuint)Unsafe.SizeOf<CacheLineHead>()) * CacheLineCount; // 16 byte align nuint entrySize = ((nuint)Unsafe.SizeOf<CacheLineHead>()) * CacheLineCount; // 16 byte align
nuint predictionSize = ((nuint)Unsafe.SizeOf<CacheLinePrediction>()) * PredictionCount; //16 byte align nuint predictionSize = ((nuint)Unsafe.SizeOf<CacheLinePrediction>()) * PredictionCount; //16 byte align
nuint mapSize = (nuint)SwissTable.RequestedNativeMemorySize; // 16 byte align nuint mapSize = SwissTable.RequestedNativeMemorySize; // 16 byte align
nuint rrpvSize = (nuint)Unsafe.SizeOf<EvictionArray>(); // 16 byte align nuint rrpvSize = (nuint)Unsafe.SizeOf<EvictionArray>(); // 16 byte align
nuint stackSize = ((nuint)sizeof(int)) * CacheLineCount; // int align nuint stackSize = ((nuint)sizeof(int)) * CacheLineCount; // int align
Numa.Free((void*)_baseAddress, _bindedNuma, cacheSize + entrySize + stackSize + mapSize + predictionSize + rrpvSize); Numa.Free((void*)_baseAddress, _bindedNuma, cacheSize + entrySize + stackSize + mapSize + predictionSize + rrpvSize);
@@ -136,9 +142,7 @@ namespace StgSharp.HighPerformance.Memory
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public L4CacheLine Map( public L4CacheLine Map(nuint origin)
nuint origin
)
{ {
if ((_aheadCount < PredictionLeastAhead) && !_exhausted) if ((_aheadCount < PredictionLeastAhead) && !_exhausted)
{ {
@@ -181,13 +185,6 @@ namespace StgSharp.HighPerformance.Memory
private partial void Prefetch(); private partial void Prefetch();
private struct CacheLineData
{
private fixed byte Data[8192];
}
} }
public ref struct L4CacheLine : IDisposable public ref struct L4CacheLine : IDisposable
@@ -197,11 +194,7 @@ namespace StgSharp.HighPerformance.Memory
private ref int _refCount; private ref int _refCount;
private nuint _handle; private nuint _handle;
internal L4CacheLine( internal L4CacheLine(nuint handle, ref int activeCount, ref int cacheRefCount)
nuint handle,
ref int activeCount,
ref int cacheRefCount
)
{ {
_handle = handle; _handle = handle;
_refCount = ref cacheRefCount; _refCount = ref cacheRefCount;
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="SlabAllocator.Fixed" // file="SlabAllocator.Fixed.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -37,7 +40,7 @@ using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory namespace StgSharp.HighPerformance.Memory
{ {
internal unsafe class FixedSlabAllocator<T> : SlabAllocator<T> where T : unmanaged internal unsafe class FixedSlabAllocator<T> : SlabAllocator<T> where T: unmanaged
{ {
private Action<nuint> _freeHandle; private Action<nuint> _freeHandle;
@@ -50,11 +53,7 @@ namespace StgSharp.HighPerformance.Memory
private nuint _Capacity, _currentIndex; private nuint _Capacity, _currentIndex;
public FixedSlabAllocator( internal FixedSlabAllocator(nuint buffer, nuint count, Action<nuint> freeHandle)
nuint buffer,
nuint count,
Action<nuint> freeHandle
)
{ {
_freeHandle = freeHandle; _freeHandle = freeHandle;
_buffer = buffer; _buffer = buffer;
@@ -109,9 +108,7 @@ namespace StgSharp.HighPerformance.Memory
public override void ExitBufferReading() { } public override void ExitBufferReading() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Free( public override void Free(nuint index)
nuint index
)
{ {
_recycle.Push(index); _recycle.Push(index);
} }
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="SlabAllocator" // file="SlabAllocator.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -56,62 +59,53 @@ namespace StgSharp.Mathematics.Memory
/// </exception> /// </exception>
/// <remarks> /// <remarks>
/// <para><strong> Important Threading Considerations: </strong></para> <para>While SLAB /// <para><strong> Important Threading Considerations: </strong></para> <para>While SLAB
/// /// allocators themselves may be designed for single-threaded use, allocated objects /// /// /// allocators themselves may be designed for single-threaded use, allocated
/// are /// frequently shared across multiple threads in real-world applications. Due to /// objects /// are /// frequently shared across multiple threads in real-world
/// the /// special implementation of expandable concurrent sequential SLAB allocators, /// applications. Due to /// the /// special implementation of expandable concurrent
/// they rely /// on internal expansion locks to ensure that memory buffer expansions /// sequential SLAB allocators, /// they rely /// on internal expansion locks to
/// (which involve /// copying the entire buffer to a new location) do not occur while /// ensure that memory buffer expansions /// (which involve /// copying the entire
/// other threads are /// reading from allocated regions. </para> <para><strong> /// buffer to a new location) do not occur while /// other threads are /// reading
/// Sequential Layout Limitations: ///</strong><br /> Sequential layout SLAB allocators /// from allocated regions. </para> <para><strong>/// Sequential Layout Limitations:
/// cannot provide a single-threaded /// version because:<list /// ///</strong><br /> Sequential layout SLAB allocators /// cannot provide a single-
/// type="bullet"><item><description>They use contiguous memory /// layout that requires /// threaded /// version because:<list /// type="bullet"><item><description>They use
/// buffer expansion when capacity is exceeded /// contiguous memory /// layout that requires /// buffer expansion when capacity is
/// ///</description></item><item><description>Buffer expansion involves copying all /// /// exceeded /// ///</description></item><item><description>Buffer expansion involves
/// existing data to a new memory location</description></item><item><description> /// /// copying all /// /// existing data to a new memory
/// Without proper synchronization, concurrent access to allocated objects during /// /// location</description></item><item><description> /// /// Without proper
/// expansion would cause memory corruption</description></item><item><description>The /// synchronization, concurrent access to allocated objects during /// /// expansion
/// /// expansion lock mechanism is essential even if allocation itself is single- /// /// would cause memory corruption</description></item><item><description>The /// ///
/// threaded </description></item></list></para> <para><strong>Chunked Layout: /// expansion lock mechanism is essential even if allocation itself is single- /// ///
/// threaded </description></item></list></para> <para><strong>Chunked Layout: ///
/// ///</strong><br /> Chunked layout allocators can optionally provide single-threaded /// ///</strong><br /> Chunked layout allocators can optionally provide single-threaded
/// /// versions since they don't require buffer expansion and copying. Each chunk is /// /// /// versions since they don't require buffer expansion and copying. Each
/// /// allocated independently, avoiding the memory relocation issues present in /// chunk is /// /// allocated independently, avoiding the memory relocation issues
/// sequential /// layouts. </para> /// present in /// sequential /// layouts. </para>
/// </remarks> /// </remarks>
public static SlabAllocator<T> Create<T>( public static SlabAllocator<T> Create<T>(nuint count, SlabBufferLayout layout, bool concurrentSupport = true)
nuint count, where T: unmanaged
SlabBufferLayout layout,
bool concurrentSupport = true
) where T : unmanaged
{ {
if (concurrentSupport) {
return layout switch
{
SlabBufferLayout.Sequential => new ConcurrentSequentialSlabAllocator<T>(count),
SlabBufferLayout.Chunked => new ConcurrentChunkedSlabAllocator<T>(count),
_ => throw new ArgumentOutOfRangeException(nameof(layout), layout, null)
};
}
return layout switch return layout switch
{ {
SlabBufferLayout.Sequential => throw new NotSupportedException("Non-concurrent version of sequential layout SLAB is not supported due to expansion lock requirements for memory safety during buffer expansion."), SlabBufferLayout.Sequential => concurrentSupport ?
SlabBufferLayout.Chunked => new ChunkedSlabAllocator<T>(count), new ConcurrentSequentialSlabAllocator<T>(count) :
throw new NotSupportedException("Non-concurrent version of sequential layout SLAB is not supported due to expansion lock requirements for memory safety during buffer expansion."),
SlabBufferLayout.Chunked => concurrentSupport ?
new ConcurrentChunkedSlabAllocator<T>(count) :
new ChunkedSlabAllocator<T>(count),
_ => throw new ArgumentOutOfRangeException(nameof(layout), layout, null) _ => throw new ArgumentOutOfRangeException(nameof(layout), layout, null)
}; };
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SlabAllocator<T> FromBuffer<T>( public static SlabAllocator<T> FromBuffer<T>(nuint buffer, nuint count, Action<nuint> freeHandle)
nuint buffer, where T: unmanaged
nuint count,
Action<nuint> freeHandle
) where T : unmanaged
{ {
return new FixedSlabAllocator<T>(buffer, count, freeHandle); return new FixedSlabAllocator<T>(buffer, count, freeHandle);
} }
} }
public abstract class SlabAllocator<T> : IDisposable where T : unmanaged public abstract class SlabAllocator<T> : IDisposable where T: unmanaged
{ {
public abstract nuint Allocate(); public abstract nuint Allocate();
@@ -122,9 +116,7 @@ namespace StgSharp.Mathematics.Memory
public abstract void ExitBufferReading(); public abstract void ExitBufferReading();
public abstract void Free( public abstract void Free(nuint index);
nuint index
);
public abstract SlabAllocationHandle<T> ReadAllocation(); public abstract SlabAllocationHandle<T> ReadAllocation();
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="Matrix.Create" // file="Matrix.Create.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload Space // AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -74,7 +77,7 @@ namespace StgSharp.Mathematics.Numeric
long requiredBytes = kernelCount * MatrixKernel<T>.Size; long requiredBytes = kernelCount * MatrixKernel<T>.Size;
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(requiredBytes, nameof(requiredBytes)); ArgumentOutOfRangeException.ThrowIfNegativeOrZero(requiredBytes, nameof(requiredBytes));
HybridLayerSegregatedFitAllocationHandle handle = allocator.Alloc((uint)requiredBytes); hlsfHandle handle = allocator.Alloc((uint)requiredBytes);
MatrixStorageHLSF<T> storage = new MatrixStorageHLSF<T>(allocator, handle); MatrixStorageHLSF<T> storage = new MatrixStorageHLSF<T>(allocator, handle);
Matrix<T> matrix = new Matrix<T>(MatrixKernelBoarder.Create(layout), new MatrixSize(columnLength, rowLength, Matrix<T> matrix = new Matrix<T>(MatrixKernelBoarder.Create(layout), new MatrixSize(columnLength, rowLength,
@@ -36,7 +36,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using HLSFAllocator = global::StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocator; using HLSFAllocator = global::StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocator;
using HLSFHandle = global::StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocationHandle; using HLSFHandle = global::StgSharp.Mathematics.Memory.hlsfHandle;
namespace StgSharp.Mathematics.Numeric namespace StgSharp.Mathematics.Numeric
{ {
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="MatrixEnumerator" // file="MatrixEnumerator.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -44,8 +47,7 @@ namespace StgSharp.Mathematics.Numeric.Runtime
} }
public unsafe interface IMatrixCachePredictor<TSelf> : IL4Predict public unsafe interface IMatrixCachePredictor<TSelf> : IL4Predict where TSelf: class, IMatrixCachePredictor<TSelf>
where TSelf : class, IMatrixCachePredictor<TSelf>
{ {
public static abstract PredictPolicy Policy { get; set; } public static abstract PredictPolicy Policy { get; set; }
@@ -60,36 +62,22 @@ namespace StgSharp.Mathematics.Numeric.Runtime
public static PredictPolicy Policy { get; set; } = PredictPolicy.SquareRowMajor; public static PredictPolicy Policy { get; set; } = PredictPolicy.SquareRowMajor;
public bool IsSamePolicy( public bool IsSamePolicy(uint policy, IL4Predict predict)
uint policy,
IL4Predict predict
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public PredictResult Predict( public PredictResult Predict(Span<CacheLinePrediction> node, out int count)
Span<CacheLinePrediction> node,
out int count
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void Prefetch( public void Prefetch(nuint origin, uint policy, Span<byte> cache)
nuint origin,
uint policy,
Span<byte> cache
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void WriteBack( public void WriteBack(nuint origin, uint policy, ReadOnlySpan<byte> cache)
nuint origin,
uint policy,
ReadOnlySpan<byte> cache
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
+32 -29
View File
@@ -1,27 +1,30 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="HlsfStressTest" // file="HlsfStressTest.cs"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload Space // AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person
// of this software and associated documentation files (the "Software"), to deal // obtaining a copy of this software and associated documentation
// in the Software without restriction, including without limitation the rights // files (the “Software”), to deal in the Software without restriction,
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // including without limitation the rights to use, copy, modify, merge,
// copies of the Software, and to permit persons to whom the Software is // publish, distribute, sublicense, and/or sell copies of the Software,
// furnished to do so, subject to the following conditions: // and to permit persons to whom the Software is furnished to do so,
// // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. // The above copyright notice and
// // this permission notice shall be included in all copies
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // or substantial portions of the Software.
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // THE SOFTWARE IS PROVIDED “AS IS”,
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// SOFTWARE. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -149,7 +152,7 @@ namespace StgSharp
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < pairs; i++) for (int i = 0; i < pairs; i++)
{ {
HybridLayerSegregatedFitAllocationHandle h = allocator.Alloc(blockSize); hlsfHandle h = allocator.Alloc(blockSize);
allocator.Free(h); allocator.Free(h);
} }
sw.Stop(); sw.Stop();
@@ -175,11 +178,11 @@ namespace StgSharp
return; return;
} }
List<HybridLayerSegregatedFitAllocationHandle> list = new List<HybridLayerSegregatedFitAllocationHandle>((int)ops); List<hlsfHandle> list = new List<hlsfHandle>((int)ops);
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
for (long i = 0; i < ops; i++) for (long i = 0; i < ops; i++)
{ {
HybridLayerSegregatedFitAllocationHandle h = allocator.Alloc(blockSize); hlsfHandle h = allocator.Alloc(blockSize);
if (touch) if (touch)
{ {
Span<byte> span = h.BufferHandle; Span<byte> span = h.BufferHandle;
@@ -193,7 +196,7 @@ namespace StgSharp
} }
sw.Stop(); sw.Stop();
double allocOpsPerSec = ops / sw.Elapsed.TotalSeconds; double allocOpsPerSec = ops / sw.Elapsed.TotalSeconds;
foreach (HybridLayerSegregatedFitAllocationHandle h in list) { foreach (hlsfHandle h in list) {
allocator.Free(h); allocator.Free(h);
} }
@@ -205,13 +208,13 @@ namespace StgSharp
{ {
int targetBytes = targetMiB * 1024 * 1024; int targetBytes = targetMiB * 1024 * 1024;
Random rng = new Random(123); Random rng = new Random(123);
List<HybridLayerSegregatedFitAllocationHandle> live = new List<HybridLayerSegregatedFitAllocationHandle>(128 * 1024); List<hlsfHandle> live = new List<hlsfHandle>(128 * 1024);
long allocated = 0; long allocated = 0;
Stopwatch swA = Stopwatch.StartNew(); Stopwatch swA = Stopwatch.StartNew();
while (allocated < targetBytes) while (allocated < targetBytes)
{ {
uint sz = PickSize(rng); uint sz = PickSize(rng);
HybridLayerSegregatedFitAllocationHandle h = allocator.Alloc(sz); hlsfHandle h = allocator.Alloc(sz);
live.Add(h); live.Add(h);
allocated += sz; allocated += sz;
} }
@@ -235,7 +238,7 @@ namespace StgSharp
while (allocated < targetBytes / 2) while (allocated < targetBytes / 2)
{ {
uint sz = PickSize(rng); uint sz = PickSize(rng);
HybridLayerSegregatedFitAllocationHandle h = allocator.Alloc(sz); hlsfHandle h = allocator.Alloc(sz);
live.Add(h); live.Add(h);
allocated += sz; allocated += sz;
reCount++; reCount++;
@@ -244,7 +247,7 @@ namespace StgSharp
Console.WriteLine($" phaseC re-alloc {reCount} in {swC.Elapsed.TotalSeconds:0.00}s ~{allocated / (1024.0 * 1024.0):0}MB"); Console.WriteLine($" phaseC re-alloc {reCount} in {swC.Elapsed.TotalSeconds:0.00}s ~{allocated / (1024.0 * 1024.0):0}MB");
Stopwatch swD = Stopwatch.StartNew(); Stopwatch swD = Stopwatch.StartNew();
foreach (HybridLayerSegregatedFitAllocationHandle h in live) { foreach (hlsfHandle h in live) {
allocator.Free(h); allocator.Free(h);
} }
@@ -254,7 +257,7 @@ namespace StgSharp
private static void BenchFreeThroughput(HybridLayerSegregatedFitAllocator allocator, int count, uint blockSize) private static void BenchFreeThroughput(HybridLayerSegregatedFitAllocator allocator, int count, uint blockSize)
{ {
List<HybridLayerSegregatedFitAllocationHandle> list = new List<HybridLayerSegregatedFitAllocationHandle>(count); List<hlsfHandle> list = new List<hlsfHandle>(count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
list.Add(allocator.Alloc(blockSize)); list.Add(allocator.Alloc(blockSize));
} }
@@ -292,12 +295,12 @@ namespace StgSharp
private static void Warmup(HybridLayerSegregatedFitAllocator allocator) private static void Warmup(HybridLayerSegregatedFitAllocator allocator)
{ {
List<HybridLayerSegregatedFitAllocationHandle> tmp = new List<HybridLayerSegregatedFitAllocationHandle>(4096); List<hlsfHandle> tmp = new List<hlsfHandle>(4096);
for (int i = 0; i < 4096; i++) { for (int i = 0; i < 4096; i++) {
tmp.Add(allocator.Alloc(256)); tmp.Add(allocator.Alloc(256));
} }
foreach (HybridLayerSegregatedFitAllocationHandle h in tmp) { foreach (hlsfHandle h in tmp) {
allocator.Free(h); allocator.Free(h);
} }
} }
+1 -1
View File
@@ -59,7 +59,7 @@ namespace StgSharp
for (int round = 1; round <= maxRounds; round++) for (int round = 1; round <= maxRounds; round++)
{ {
// 100 次分配 // 100 次分配
List<HybridLayerSegregatedFitAllocationHandle> batch = new List<HybridLayerSegregatedFitAllocationHandle>(100); List<hlsfHandle> batch = new List<hlsfHandle>(100);
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
uint sz = sizes[rnd.Next(sizes.Length)]; uint sz = sizes[rnd.Next(sizes.Length)];