Enhance memory management and performance benchmarks
Added a new configuration setting in `.editorconfig` to sort system directives last and increased the maximum line length to 400 characters. Added a new static class `MathUtilities` in `MathUtilities.cs` with a method `CeilPow2` for computing powers of two. Added a new benchmark class `CollectionBenchmark` in `CollectionBenchmark.cs` to measure performance of standard versus unsafe arrays. Added a new benchmark class `HashCodeBenchmark` in `HashCodeBenchmark.cs` to evaluate hash code generation performance. Added new utility methods in `UnsafeUtilities.cs` for memory allocation and deallocation, including `Malloc`, `AlignedAlloc`, `Realloc`, and `Free`. Added a new `AllocationType` enum in `AllocationType.cs` to specify memory allocation types. Changed the project file `Misaki.HighPerformance.Mathematics.csproj` to target .NET 9.0 and enable implicit usings and nullable reference types. Changed the `ParallelNoiseBenchmark` class in `ParallelNoiseBenchmark.cs` to improve memory allocation strategies and performance. Changed memory management in `Arena.cs` and `DynamicArena.cs` to use custom `Malloc` and `Free` functions. Changed the `IUnsafeCollection` interface in `IUnsafeCollection.cs` to include new methods for resizing collections and obtaining unsafe pointers. Changed the `UnsafeArray.cs` to improve management of unsafe arrays, including constructor and method updates. Changed the `UnsafeHashMap` and `UnsafeHashSet` classes to enhance performance and memory management. Changed the `UnsafeCollectionExtensions` class to provide additional methods for copying elements and converting collections. Changed the `ObjectPool` class in `ObjectPool.cs` to simplify cleanup and remove auto-cleanup functionality. Changed job scheduling and worker classes in `JobExtensions.cs` and `JobWorker.cs` to improve job scheduling in a thread pool. Removed commented-out code in `Program.cs` related to previous testing methods. Removed auto-cleanup functionality from the `ObjectPool` class.
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace Misaki.HighPerformance.Unsafe.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for copying elements between unsafe collections and spans, converting collections to
|
||||
/// arrays or lists, and searching for values.
|
||||
/// </summary>
|
||||
public unsafe static class UnsafeCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -13,14 +17,37 @@ public unsafe static class UnsafeCollectionExtensions
|
||||
/// <exception cref="ArgumentException">Thrown when the sizes of the source collection and destination span do not match.</exception>
|
||||
public static void CopyTo<T>(this IUnsafeCollection<T> source, Span<T> destination) where T : unmanaged
|
||||
{
|
||||
if (source.Size > destination.Length)
|
||||
if (source.Count > destination.Length)
|
||||
{
|
||||
throw new ArgumentException("Source collection is larger than the destination span.");
|
||||
}
|
||||
|
||||
fixed (T* ptr = destination)
|
||||
{
|
||||
SystemUnsfae.CopyBlock(ptr, source.Buffer, (uint)(source.Size * sizeof(T)));
|
||||
SystemUnsfae.CopyBlock(ptr, source.GetUnsafePtr(), (uint)(source.Count * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a range of elements from a source collection to a destination span, ensuring both are adequately sized.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Specifies the type of elements being copied, which must be a value type.</typeparam>
|
||||
/// <param name="source">The collection from which elements are copied.</param>
|
||||
/// <param name="destination">The span where the elements will be copied to.</param>
|
||||
/// <param name="sourceIndex">The starting index in the source collection for the copy operation.</param>
|
||||
/// <param name="destinationIndex">The starting index in the destination span where the elements will be placed.</param>
|
||||
/// <param name="length">The number of elements to copy from the source to the destination.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when the specified range exceeds the bounds of the source collection or destination span.</exception>
|
||||
public static void CopyTo<T>(this IUnsafeCollection<T> source, Span<T> destination, int sourceIndex, int destinationIndex, int length) where T : unmanaged
|
||||
{
|
||||
if (sourceIndex + length > source.Count || destinationIndex + length > destination.Length)
|
||||
{
|
||||
throw new ArgumentException("Source collection or destination span is too small for the specified range.");
|
||||
}
|
||||
|
||||
fixed (T* ptr = destination)
|
||||
{
|
||||
SystemUnsfae.CopyBlock(ptr + destinationIndex, (byte*)source.GetUnsafePtr() + (sourceIndex * sizeof(T)), (uint)(length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,14 +60,37 @@ public unsafe static class UnsafeCollectionExtensions
|
||||
/// <exception cref="ArgumentException">Thrown when the source span and destination collection have different sizes.</exception>
|
||||
public static void CopyFrom<T>(this IUnsafeCollection<T> destination, Span<T> source) where T : unmanaged
|
||||
{
|
||||
if (destination.Size > source.Length)
|
||||
if (destination.Count > source.Length)
|
||||
{
|
||||
throw new ArgumentException("Destination collection is larger than the source span.");
|
||||
}
|
||||
|
||||
fixed (T* ptr = source)
|
||||
{
|
||||
SystemUnsfae.CopyBlock(destination.Buffer, ptr, (uint)(source.Length * sizeof(T)));
|
||||
SystemUnsfae.CopyBlock(destination.GetUnsafePtr(), ptr, (uint)(source.Length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a specified range of elements from a source span to a destination collection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Represents the type of elements being copied, which must be unmanaged.</typeparam>
|
||||
/// <param name="destination">The collection where elements will be copied to.</param>
|
||||
/// <param name="source">The span containing the elements to be copied.</param>
|
||||
/// <param name="sourceIndex">The starting index in the source span from which to begin copying.</param>
|
||||
/// <param name="destinationIndex">The starting index in the destination collection where the elements will be placed.</param>
|
||||
/// <param name="length">The number of elements to copy from the source span to the destination collection.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when the specified range exceeds the bounds of the source span or destination collection.</exception>
|
||||
public static void CopyFrom<T>(this IUnsafeCollection<T> destination, Span<T> source, int sourceIndex, int destinationIndex, int length) where T : unmanaged
|
||||
{
|
||||
if (sourceIndex + length > source.Length || destinationIndex + length > destination.Count)
|
||||
{
|
||||
throw new ArgumentException("Source span or destination collection is too small for the specified range.");
|
||||
}
|
||||
|
||||
fixed (T* ptr = source)
|
||||
{
|
||||
SystemUnsfae.CopyBlock((byte*)destination.GetUnsafePtr() + (destinationIndex * sizeof(T)), ptr + sourceIndex, (uint)(length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,10 +102,10 @@ public unsafe static class UnsafeCollectionExtensions
|
||||
/// <returns>A new collection containing the elements from the UnsafeCollection.</returns>
|
||||
public static T[] ToArray<T>(this IUnsafeCollection<T> source) where T : unmanaged
|
||||
{
|
||||
var array = new T[source.Size];
|
||||
var array = new T[source.Count];
|
||||
fixed (T* ptr = array)
|
||||
{
|
||||
SystemUnsfae.CopyBlock(ptr, source.Buffer, (uint)(source.Size * sizeof(T)));
|
||||
SystemUnsfae.CopyBlock(ptr, source.GetUnsafePtr(), (uint)(source.Count * sizeof(T)));
|
||||
}
|
||||
|
||||
return array;
|
||||
@@ -69,10 +119,10 @@ public unsafe static class UnsafeCollectionExtensions
|
||||
/// <returns>A list containing the elements from the specified unmanaged collection.</returns>
|
||||
public static List<T> ToList<T>(this IUnsafeCollection<T> source) where T : unmanaged
|
||||
{
|
||||
var list = new List<T>(source.Size);
|
||||
var list = new List<T>(source.Count);
|
||||
fixed (T* ptr = list.ToArray())
|
||||
{
|
||||
SystemUnsfae.CopyBlock(ptr, source.Buffer, (uint)(source.Size * sizeof(T)));
|
||||
SystemUnsfae.CopyBlock(ptr, source.GetUnsafePtr(), (uint)(source.Count * sizeof(T)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -85,6 +135,39 @@ public unsafe static class UnsafeCollectionExtensions
|
||||
/// <returns>A Span that provides a view over the elements of the UnsafeCollection.</returns>
|
||||
public static Span<T> AsSpan<T>(this IUnsafeCollection<T> source) where T : unmanaged
|
||||
{
|
||||
return new(source.Buffer, source.Size);
|
||||
return new(source.GetUnsafePtr(), source.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the index of a specified value in a collection. Returns -1 if the value is not found.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of elements in the collection, which must support equality comparison.</typeparam>
|
||||
/// <param name="source">The collection to search for the specified value.</param>
|
||||
/// <param name="value">The value to locate within the collection.</param>
|
||||
/// <param name="index">Outputs the index of the found value or -1 if not found.</param>
|
||||
public static void IndexOf<T>(this IUnsafeCollection<T> source, T value, out int index) where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
for (var i = 0; i < source.Count; i++)
|
||||
{
|
||||
if (UnsafeUtilities.ReadArrayElement<T>(source.GetUnsafePtr(), i).Equals(value))
|
||||
{
|
||||
index = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
index = -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a specified value exists within an unsafe collection of unmanaged types.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Represents a type that is unmanaged and supports equality comparison.</typeparam>
|
||||
/// <param name="source">The collection being searched for the specified value.</param>
|
||||
/// <param name="value">The value being searched for within the collection.</param>
|
||||
/// <returns>Returns true if the value is found; otherwise, returns false.</returns>
|
||||
public static bool Conations<T>(this IUnsafeCollection<T> source, T value) where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
source.IndexOf(value, out var index);
|
||||
return index != -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user