Refactor allocation types and improve memory management
This commit renames `AllocationType` to `AllocationOption` across multiple files, enhancing clarity in memory allocation practices. Key updates include: - Modifications to the `UnsafeArray`, `ParallelNoiseBenchmark`, `Arena`, and `DynamicArena` classes to utilize the new `AllocationOption`. - Refactoring of the `AllocationManager` and `HashMapHelper` classes to support the new allocation strategy. - Removal of the `Misaki.HighPerformance.Mathematics` project reference, indicating a restructuring of dependencies. - Introduction of a new `MathUtilities` class for calculating the smallest power of two, aiding memory allocation strategies. These changes collectively improve code maintainability and clarity in memory management.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
namespace Misaki.HighPerformance.Unsafe.Collections;
|
||||
|
||||
public enum AllocationOption : byte
|
||||
{
|
||||
UnInitialized,
|
||||
Clear
|
||||
}
|
||||
|
||||
public enum Allocator: byte
|
||||
{
|
||||
// Make the first allocator as invalid because we don't want to user create a defualt collection without passing any parameters
|
||||
Invalid = 0,
|
||||
Temp = 1,
|
||||
Persistent = 2,
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Misaki.HighPerformance.Unsafe.Collections;
|
||||
|
||||
public enum AllocationType
|
||||
{
|
||||
UnInitialized,
|
||||
Clear
|
||||
}
|
||||
|
||||
public enum Allocator
|
||||
{
|
||||
Temp,
|
||||
Persistent
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using Misaki.HighPerformance.Unsafe.Buffer;
|
||||
|
||||
namespace Misaki.HighPerformance.Unsafe.Collections.Services;
|
||||
|
||||
public static unsafe class AllocationManager
|
||||
{
|
||||
private static DynamicArena _arena;
|
||||
private static bool _initialized;
|
||||
|
||||
private static readonly Lock _lock = new();
|
||||
|
||||
public static void Initialize(uint initialSize)
|
||||
{
|
||||
_arena = new DynamicArena(initialSize);
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
public static T* Allocate<T>(uint size, uint alignSize, Allocator allocator, AllocationType allocationType)
|
||||
where T : unmanaged
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
throw new InvalidOperationException("The AllocationManager has not been initialized.");
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
return allocator switch
|
||||
{
|
||||
Allocator.Temp => (T*)_arena.Allocate(size * (uint)sizeof(T), alignSize, allocationType),
|
||||
Allocator.Persistent => (T*)AlignedAlloc((nuint)(size * sizeof(T)), alignSize),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(allocator), "Invalid allocator type."),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reset(bool clear = false)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
throw new InvalidOperationException("The AllocationManager has not been initialized.");
|
||||
}
|
||||
|
||||
_arena.Reset(clear);
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
_arena.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Misaki.HighPerformance.Unsafe.Collections.Contracts;
|
||||
using Misaki.HighPerformance.Unsafe.Collections.Services;
|
||||
using Misaki.HighPerformance.Unsafe.Helpers;
|
||||
using Misaki.HighPerformance.Unsafe.Services;
|
||||
using System.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
@@ -66,6 +66,8 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
private T* _buffer;
|
||||
private int _count;
|
||||
|
||||
private readonly Allocator _allocator;
|
||||
|
||||
public readonly int Count => _count;
|
||||
|
||||
public readonly ref T this[int index]
|
||||
@@ -90,7 +92,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
/// <param name="count">Specifies the number of elements to allocate in the array, which must be greater than zero.</param>
|
||||
/// <param name="allocationType">Determines how the allocated memory should be initialized, either uninitialized or cleared.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the specified number of elements is less than or equal to zero.</exception>
|
||||
public UnsafeArray(int count, Allocator allocator, AllocationType allocationType = AllocationType.UnInitialized)
|
||||
public UnsafeArray(int count, Allocator allocator, AllocationOption allocationType = AllocationOption.UnInitialized)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
@@ -100,7 +102,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
_buffer = AllocationManager.Allocate<T>((uint)count, (uint)AlignOf<T>(), allocator, allocationType);
|
||||
_count = count;
|
||||
|
||||
if (allocationType == AllocationType.Clear)
|
||||
if (allocationType == AllocationOption.Clear)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
@@ -132,7 +134,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly void Clear()
|
||||
{
|
||||
MemClear(_buffer, (uint)(_count * sizeof(T)));
|
||||
MemClear(_buffer, (nuint)(_count * sizeof(T)));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -143,7 +145,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AlignedFree(_buffer);
|
||||
AllocationManager.Free(_buffer, _allocator);
|
||||
|
||||
_buffer = null;
|
||||
_count = 0;
|
||||
|
||||
@@ -92,9 +92,9 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeCollection<KeyValuePai
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => new Enumerator((HashMapHelper<TKey>*)UnsafeUtilities.AddressOf(ref _hashMap));
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
public UnsafeHashMap(int capacity)
|
||||
public UnsafeHashMap(int capacity, Allocator allocator)
|
||||
{
|
||||
_hashMap = new HashMapHelper<TKey>(capacity, sizeof(TValue), HashMapHelper<TKey>.MINIMAL_CAPACITY);
|
||||
_hashMap = new HashMapHelper<TKey>(capacity, sizeof(TValue), HashMapHelper<TKey>.MINIMAL_CAPACITY, allocator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -49,9 +49,9 @@ public unsafe struct UnsafeHashSet<T> : IUnsafeCollection<T>, IEnumerable<T>
|
||||
public IEnumerator<T> GetEnumerator() => new Enumerator((HashMapHelper<T>*)UnsafeUtilities.AddressOf(ref _hashMap));
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
public UnsafeHashSet(int capacity)
|
||||
public UnsafeHashSet(int capacity, Allocator allocator)
|
||||
{
|
||||
_hashMap = new HashMapHelper<T>(capacity, 0, HashMapHelper<T>.MINIMAL_CAPACITY);
|
||||
_hashMap = new HashMapHelper<T>(capacity, 0, HashMapHelper<T>.MINIMAL_CAPACITY, allocator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -129,12 +129,12 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
public ParallelWriter AsParallelWriter() => new((UnsafeList<T>*)UnsafeUtilities.AddressOf(ref this));
|
||||
|
||||
public UnsafeList(int capacity, Allocator allocator, AllocationType allocationType = AllocationType.UnInitialized)
|
||||
public UnsafeList(int capacity, Allocator allocator, AllocationOption allocationType = AllocationOption.UnInitialized)
|
||||
{
|
||||
_array = new UnsafeArray<T>(capacity, allocator, allocationType);
|
||||
_count = 0;
|
||||
|
||||
if (allocationType == AllocationType.Clear)
|
||||
if (allocationType == AllocationOption.Clear)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
@@ -80,13 +80,13 @@ public unsafe struct UnsafeQueue<T> : IUnsafeCollection<T>
|
||||
public IEnumerator<T> GetEnumerator() => new Enumerator((UnsafeQueue<T>*)UnsafeUtilities.AddressOf(ref this));
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
public UnsafeQueue(int capacity, Allocator allocator, AllocationType allocationType = AllocationType.UnInitialized)
|
||||
public UnsafeQueue(int capacity, Allocator allocator, AllocationOption allocationType = AllocationOption.UnInitialized)
|
||||
{
|
||||
_array = new UnsafeArray<T>(capacity, allocator, allocationType);
|
||||
_count = 0;
|
||||
_offset = 0;
|
||||
|
||||
if (allocationType == AllocationType.Clear)
|
||||
if (allocationType == AllocationOption.Clear)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user