Enhance mathematical capabilities and job system

Added new numeric types for unsigned integers, including uint2, uint3, and uint4, along with their matrix types.
Added a new `quaternion` struct with constructors and methods for creating and manipulating quaternions.
Added methods for projecting and reflecting vectors, enhancing geometric operations.
Added utility functions for generating orthonormal bases and changing vector signs.
Added comprehensive unit tests for new mathematical functions and quaternion operations.
Added a high-performance job scheduling system with job management features and worker thread management.
Added new structs for job execution, allowing efficient job scheduling and execution.
Added utility functions for job execution, including methods for obtaining unique job IDs.

Changed access modifiers and property definitions in several files for improved clarity and maintainability.
Changed property definitions and method implementations in `ImageInfo.cs`, `ImageResult.cs`, and `ImageResultFloat.cs` for better readability.
Changed memory management functions in `CRuntime.cs` and improved memory allocation tracking in `MemoryStats.cs`.
Changed the project file to include references to necessary projects and enable unsafe code blocks.

Removed the `WorkerThreadPool.cs` file, integrating worker thread management directly into the `JobScheduler`.
Removed the `float4` struct and its associated methods and properties, transitioning to a new code generation strategy.
Removed the `float4.tt` template and other related files, indicating a shift in code generation approach.
Removed the `Vectorize.cs` file, indicating a change in how vector operations are handled.

Updated the `.gitignore` file to include IDE-specific settings.
Updated various XML files to define project components and structure.
Updated the `AllocationManager.cs` to improve memory allocation management and introduce new strategies.
Updated the `UnsafeArray.cs`, `UnsafeHashMap.cs`, and `UnsafeList.cs` to enhance performance and safety in unsafe contexts.
Updated error handling and function pointer management in `MemoryLeakException.cs` and `FunctionPointer.cs`.
Updated the `AssemblyInfo.cs` file to include global using directives for better code organization.
This commit is contained in:
2025-09-06 12:07:02 +09:00
parent eeff3313b5
commit a2a760594e
114 changed files with 20826 additions and 7217 deletions

View File

@@ -0,0 +1,55 @@
using BenchmarkDotNet.Attributes;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Misaki.HighPerformance.Test.Benchmark;
[MemoryDiagnoser]
public unsafe class CollectionBenchmark
{
[Params(10, 100, 1000)]
public int count;
[GlobalSetup]
public void Setup()
{
}
[Benchmark]
public void Array()
{
var array = new int[count];
for (var i = 0; i < count; i++)
{
array[i] = i;
}
}
[Benchmark(Baseline = true)]
public void UnsafeArray()
{
var array = new UnsafeArray<int>(count, Allocator.Temp);
for (var i = 0; i < count; i++)
{
array[i] = i;
}
((ArenaAllocator*)AllocationManager.TempHandle.Allocator)->Reset();
}
[Benchmark]
public void StackArray()
{
var array = stackalloc int[count];
for (var i = 0; i < count; i++)
{
array[i] = i;
}
}
[GlobalCleanup]
public void Cleanup()
{
AllocationManager.Dispose();
}
}

View File

@@ -0,0 +1,47 @@
using BenchmarkDotNet.Attributes;
using Misaki.HighPerformance.LowLevel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Misaki.HighPerformance.Test.Benchmark;
[MemoryDiagnoser]
public unsafe class FunctionPtrBenchmark
{
private delegate float FunctionPointerDelegate(float a, float b);
private float _sink;
private FunctionPointer<FunctionPointerDelegate> _addManaged;
private delegate* unmanaged<float, float, float> _addUnmanaged;
public FunctionPtrBenchmark()
{
_addManaged = new(Add);
_addUnmanaged = &AddUnmanaged;
}
private float Add(float a, float b)
{
return a + b;
}
[UnmanagedCallersOnly]
private static float AddUnmanaged(float a, float b)
{
return a + b;
}
[Benchmark(Baseline = true)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void InvokeManaged()
{
_sink = _addManaged.Delegate(1.0f, 2.0f);
}
[Benchmark]
public void InvokeUnmanaged()
{
_sink = _addUnmanaged(1.0f, 2.0f);
}
}

View File

@@ -0,0 +1,95 @@
using BenchmarkDotNet.Attributes;
using System.Numerics;
namespace Misaki.HighPerformance.Test.Benchmark;
public class HashCodeBenchmark
{
private struct Component
{
public int Value;
public int Value2;
public float Value3;
public Guid Value4;
public Matrix4x4 Value5;
public Vector4 Value6;
}
[Params(100, 1000, 10000)]
public int count;
private Component _component = new Component()
{
Value = 0,
Value2 = 1,
Value3 = 2,
Value4 = Guid.NewGuid(),
Value5 = Matrix4x4.Identity,
Value6 = Vector4.One
};
private Dictionary<Type, int> _hashCache = new();
//private UnsafeHashMap<Guid, int> _hashMap = new(16);
private bool _disposed;
//~HashCodeBenchmark()
//{
// Dispose();
//}
[Benchmark]
public void Hash()
{
for (var i = 0; i < count; i++)
{
_ = _component.GetHashCode();
}
}
[Benchmark]
public void HashWithCache()
{
for (var i = 0; i < count; i++)
{
var type = typeof(Component);
if (!_hashCache.TryGetValue(type, out var hash))
{
hash = type.GetHashCode();
_hashCache[type] = hash;
}
_ = hash;
}
}
//[Benchmark]
//public void HashWithUnsafeHashMap()
//{
// for (var i = 0; i < count; i++)
// {
// var type = _component.GetType();
// var guid = type.GUID;
// if (!_hashMap.TryGetValue(guid, out var hash))
// {
// hash = type.GetHashCode();
// _hashMap.Add(guid, hash);
// _hashMap.Test(ref _hashMap._hashMap);
// }
// _ = hash;
// }
//}
//public void Dispose()
//{
// if (_disposed)
// {
// return;
// }
// _hashMap.Dispose();
// GC.SuppressFinalize(this);
//}
}

View File

@@ -0,0 +1,114 @@
using BenchmarkDotNet.Attributes;
using Misaki.HighPerformance.LowLevel.Collections;
namespace Misaki.HighPerformance.Test.Benchmark;
public class HashMapBenchmark
{
private UnsafeHashMap<int, float> _unsafeHashMap;
private Dictionary<int, float> _dictionary = null!;
[Params(10, 100, 1000)]
public int count;
[IterationSetup]
public void Setup()
{
//_unsafeHashMap = new UnsafeHashMap<int, float>(count, Allocator.Persistent);
_dictionary = new Dictionary<int, float>(count);
for (var i = 0; i < count; i++)
{
//_unsafeHashMap.Add(i, i);
_dictionary.Add(i, i);
}
}
[Benchmark]
public void UnsafeHashMapAdd()
{
for (var i = 0; i < count; i++)
{
_unsafeHashMap.Add(count + i, i);
}
}
[Benchmark(Baseline = true)]
public void DictionaryAdd()
{
for (var i = 0; i < count; i++)
{
_dictionary.Add(count + i, i);
}
}
public void UnsafeHashMapRemove()
{
for (var i = 0; i < count; i++)
{
_unsafeHashMap.Remove(i);
}
}
public void DictionaryRemove()
{
for (var i = 0; i < count; i++)
{
_dictionary.Remove(i);
}
}
public void UnsafeHashMapRandomRead()
{
for (var i = 0; i < count; i++)
{
var value = Random.Shared.Next(0, count);
if (_unsafeHashMap.TryGetValue(value, out var result))
{
var r2 = result + result;
}
}
}
public void DictionaryRandomRead()
{
for (var i = 0; i < count; i++)
{
var value = Random.Shared.Next(0, count);
if (_dictionary.TryGetValue(value, out var result))
{
var r2 = result + result;
}
}
}
public void UnsafeHashMapRandomWrite()
{
for (var i = 0; i < count; i++)
{
var value = Random.Shared.Next(0, count);
if (_unsafeHashMap.TryGetValue(value, out var result))
{
_unsafeHashMap[value] = result + 1;
}
}
}
public void DictionaryRandomWrite()
{
for (var i = 0; i < count; i++)
{
var value = Random.Shared.Next(0, count);
if (_dictionary.TryGetValue(value, out var result))
{
_dictionary[value] = result + 1;
}
}
}
[IterationCleanup]
public void Cleanup()
{
//_unsafeHashMap.Dispose();
}
}

View File

@@ -0,0 +1,37 @@
using BenchmarkDotNet.Attributes;
using Misaki.HighPerformance.Mathematics;
using System.Numerics;
namespace Misaki.HighPerformance.Test.Benchmark;
public class MathematicsBenchmark
{
[Params(10, 100)]
public int count = 10;
[Benchmark(Baseline = true)]
public void Vector2Add()
{
var a = new Vector2(1, 2);
var b = new Vector2(5, 6);
var result = new Vector2();
for (var i = 0; i < count; i++)
{
result += a + b;
}
}
[Benchmark]
public void Float2Add()
{
var a = new float2(1);
var b = new float2(5);
var result = new float2();
for (var i = 0; i < count; i++)
{
result += a + b;
}
}
}

View File

@@ -0,0 +1,69 @@
using BenchmarkDotNet.Attributes;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using Misaki.HighPerformance.Test.Jobs;
using System.Numerics;
namespace Misaki.HighPerformance.Test.Benchmark;
[MemoryDiagnoser]
public class ParallelNoiseBenchmark
{
private const int _WIDTH = 512;
private const int _HEIGHT = 512;
private const int _LENGTH = _WIDTH * _HEIGHT;
//[GlobalSetup]
//public void Setup()
//{
// JobScheduler.Initialize();
//}
//[GlobalCleanup]
//public void Cleanup()
//{
// JobScheduler.Shutdown();
//}
//[Benchmark]
//public void JobSystem()
//{
// using var buffers = new UnsafeArray<float>(_LENGTH, Allocator.Persistent, AllocationOption.None);
// var job = new NoiseJob()
// {
// buffers = buffers,
// width = _WIDTH,
// height = _HEIGHT
// };
// var handle = job.Schedule(_LENGTH, 64);
// handle.Complete();
//}
[Benchmark]
public void ParallelFor()
{
using var buffers = new UnsafeArray<float>(_LENGTH, Allocator.Persistent, AllocationOption.None);
Parallel.For(0, _LENGTH, i =>
{
var x = i % _WIDTH;
var y = i / _HEIGHT;
var uv = new Vector2(x, y);
buffers[i] = NoiseJob.GradientNoise(uv);
});
}
[Benchmark(Baseline = true)]
public void For()
{
using var buffers = new UnsafeArray<float>(_LENGTH, Allocator.Persistent, AllocationOption.None);
for (var i = 0; i < _LENGTH; i++)
{
var x = i % _WIDTH;
var y = i / _HEIGHT;
var uv = new Vector2(x, y);
buffers[i] = NoiseJob.GradientNoise(uv);
}
}
}