diff --git a/StgSharp.Common/Mathematics/Linear/Matrix.cs b/StgSharp.Common/Mathematics/Linear/Matrix.cs index ad421f3d..5bec2fdd 100644 --- a/StgSharp.Common/Mathematics/Linear/Matrix.cs +++ b/StgSharp.Common/Mathematics/Linear/Matrix.cs @@ -31,7 +31,7 @@ using StgSharp.HighPerformance; using System; using System.Numerics; - +using System.Runtime.CompilerServices; using hlsfAllocator = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator; using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle; @@ -65,8 +65,22 @@ namespace StgSharp.Mathematics protected int KernelRowCount { get; init; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix FromHlsf(int column, int row, hlsfAllocator allocator) + { + return new HlsfMatrix(column, row, allocator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public abstract MatrixSegmentEnumeration GetColumnEnumeration(); + public abstract ref MatrixKernel GetMatrixKernel(int column, int row); + public abstract MatrixSegmentEnumeration GetRowEnumeration(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public abstract MatrixSegmentEnumeration GetSequentialEnumeration(); + [Obsolete("This method does not contain boarder check, so be careful on size or use indexer instead.", false)] public abstract ref T UnsafeIndex(int column, int row); @@ -81,102 +95,109 @@ namespace StgSharp.Mathematics } } - } - - internal unsafe class GCMatrix : Matrix where T: unmanaged, INumber - { - - private readonly MatrixKernel[,] buffer; - - public GCMatrix(int column, int row) + public readonly unsafe ref struct MatrixSegmentEnumeration( + MatrixKernel* source, + int size, + int stride, + int secondaryStride) { - KernelColumnCount = (column + 3) / 4; - KernelRowCount = (row + 3) / t_count; - buffer = new MatrixKernel[KernelColumnCount, KernelRowCount]; - } - public override ref T this[int column, int row] - { - get + private readonly MatrixKernel* _source = source; + private readonly int _secondaryStride = secondaryStride; + private readonly int _size = size; + private readonly int _stride = stride; + + public Enumerator GetEnumerator() { - AssertIndex(column, row); - int kernelColumn = column / 4, c = column % 4; - int kernelRow = row / t_count, r = row % t_count; - ref MatrixKernel kernel = ref buffer[kernelColumn, kernelRow]; - return ref kernel.UnsafeIndex(c, r); + return new Enumerator(_source, _size, _stride, _size, _secondaryStride); } - } - public override Matrix this[ReadOnlySpan column, ReadOnlySpan row] - { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - - public override unsafe ref MatrixKernel GetMatrixKernel(int column, int row) - { - AssertIndex(column, row); - int kernelColumn = column / 4; - int kernelRow = row / t_count; - return ref buffer[kernelColumn, kernelRow]; - } - - public override ref T UnsafeIndex(int column, int row) - { - int kernelColumn = column / 4, c = column % 4; - int kernelRow = row / t_count, r = row % t_count; - ref MatrixKernel kernel = ref buffer[kernelColumn, kernelRow]; - return ref kernel.UnsafeIndex(c, r); - } - - } - - internal unsafe class HlsfMatrix : Matrix where T: unmanaged, INumber - { - - private readonly MatrixKernel* k_buffer; - private readonly hlsfHandle handle; - - internal HlsfMatrix(int column, int row, hlsfAllocator allocator) - { - KernelColumnCount = (column + 3) / 4; - KernelRowCount = (row + 3) / t_count; - this.handle = allocator.Alloc((uint)(KernelColumnCount * KernelRowCount * sizeof(MatrixKernel))); - k_buffer = (MatrixKernel*)handle.Pointer; - } - - public override ref T this[int column, int row] - { - get + public ref struct Enumerator(MatrixKernel* source, int end, int stride, int size, int secondaryStride) { - AssertIndex(column, row); - int kernelColumn = column / 4, c = column % 4; - int kernelRow = row / t_count, r = row % t_count; - ref MatrixKernel kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow]; - return ref kernel.UnsafeIndex(c, r); + + private MatrixKernel* _current = source - stride; + private readonly MatrixKernel* _end = source + end; + private readonly MatrixKernel* _source = source; + private readonly int _secondaryStride = secondaryStride; + private readonly int _size = size; + private readonly int _stride = stride; + + public readonly MatrixSegment Current + { +[MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(_current, _size, _secondaryStride); + } + + public readonly void Dispose() { } + + public bool MoveNext() + { + _current += _stride; + return _current < _end; + } + + public void Reset() + { + _current = _source - _stride; + } + } + } - public override Matrix this[ReadOnlySpan column, ReadOnlySpan row] + public readonly unsafe ref struct MatrixSegment(MatrixKernel* source, int size, int stride) { - get => throw new NotImplementedException(); - set => throw new NotImplementedException(); - } - public override unsafe ref MatrixKernel GetMatrixKernel(int column, int row) - { - AssertIndex(column, row); - int kernelColumn = column / 4, c = column % 4; - int kernelRow = row / t_count, r = row % t_count; - return ref k_buffer[(kernelColumn * kernelColumn) + kernelRow]; - } + private readonly MatrixKernel* _source = source; + private readonly int _size = size; + private readonly int _stride = stride; + + public ref MatrixKernel this[int index] + { + get + { + if (index < 0 || index >= _size) { + throw new ArgumentOutOfRangeException(nameof(index)); + } + return ref _source[index * _stride]; + } + } + + public Enumerator GetEnumerator() + { + return new Enumerator(_source, _size, _stride); + } + + public ref struct Enumerator(MatrixKernel* source, int end, int stride) + { + + private readonly MatrixKernel* _end = source + end; + private readonly MatrixKernel* _source = source; + private readonly int _stride = stride; + + public MatrixKernel* Current + { +[MethodImpl(MethodImplOptions.AggressiveInlining)] + get; +[MethodImpl(MethodImplOptions.AggressiveInlining)] + private set; + } = source - stride; + + public void Dispose() { } + + public bool MoveNext() + { + Current += _stride; + return Current < _end; + } + + public void Reset() + { + Current = _source - _stride; + } + + } - public override ref T UnsafeIndex(int column, int row) - { - int kernelColumn = column / 4, c = column % 4; - int kernelRow = row / t_count, r = row % t_count; - ref MatrixKernel kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow]; - return ref kernel.UnsafeIndex(c, r); } } diff --git a/StgSharpDebug/Program.cs b/StgSharpDebug/Program.cs index abf5e7be..d0ded01c 100644 --- a/StgSharpDebug/Program.cs +++ b/StgSharpDebug/Program.cs @@ -32,6 +32,7 @@ using StgSharp.Collections; using StgSharp.Controlling.UsrActivity; using StgSharp.Geometries; using StgSharp.Graphics; +using StgSharp.HighPerformance; using StgSharp.HighPerformance.Memory; using StgSharp.Mathematics; using StgSharp.Model.Step; @@ -56,116 +57,25 @@ namespace StgSharp internal static unsafe void Main(string[] args) { - /* + World.Init(); + /**/ try { - /**/ - World.Init(); + HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400); - // HLSF test arena - Console.WriteLine( - "=== HLSF (Hybrid Layer Segregated Fit Allocator) Single-threaded Stress Test ===\n"); + Matrix m = Matrix.FromHlsf(400, 400, hlsf); - - // 使用适中的内存池大小 - HybridLayerSegregatedFitAllocator hlsfAllocator = new HybridLayerSegregatedFitAllocator(16 * 1024 * 1024); - - Console.WriteLine("开始单线程压力测试...\n"); - - - // 单线程压力测试:适度的分配和释放操作 - int totalCycles = 5; - int allocationsPerCycle = 1024 * 64; // 65536 次分配 - - for (int cycle = 0; cycle < totalCycles; cycle++) - { - Console.WriteLine($"\n=== 第 {cycle + 1} 轮压力测试 ==="); - - // 预生成随机数 - uint[] randomSizes = new uint[allocationsPerCycle]; - Random random = new Random(cycle); - for (int i = 0; i < allocationsPerCycle; i++) { - randomSizes[i] = (uint)(64 + random.Next(1024 - 64 + 1)); + int i = 0, ii = 0; + foreach (Matrix.MatrixSegment lines in m.GetColumnEnumeration()) + { + foreach (MatrixKernel* item in lines) + { + i++; + Console.WriteLine(i); + } + ii++; + Console.WriteLine($"============================{ii}"); } - - // 分配阶段 - List handles = new List(allocationsPerCycle); - Stopwatch stopwatch = Stopwatch.StartNew(); - - for (int i = 0; i < allocationsPerCycle; i++) { - handles.Add(hlsfAllocator.Alloc(randomSizes[i])); - } - - stopwatch.Stop(); - Console.WriteLine($"分配完成,总计分配 {handles.Count} 个块"); - Console.WriteLine($"分配耗时: {stopwatch.ElapsedMilliseconds} ms"); - if (stopwatch.ElapsedMilliseconds > 0) { - Console.WriteLine($"分配速度: {allocationsPerCycle * 1000 / stopwatch.ElapsedMilliseconds} allocs/sec"); - } - - - // 随机释放阶段 - stopwatch.Restart(); - - for (int i = handles.Count - 1; i >= 0; i--) { - hlsfAllocator.Free(handles[i]); - } - - stopwatch.Stop(); - Console.WriteLine($"释放完成,总计释放 {handles.Count} 个块"); - Console.WriteLine($"释放耗时: {stopwatch.ElapsedMilliseconds} ms"); - if (stopwatch.ElapsedMilliseconds > 0) { - Console.WriteLine($"释放速度: {handles.Count * 1000 / stopwatch.ElapsedMilliseconds} frees/sec"); - } - - handles.Clear(); - } - - Console.WriteLine("\n=== 边界测试 ==="); - - - // 测试最小分配 - Console.WriteLine("测试最小分配 (64字节)..."); - List minHandles = new List(); - for (int i = 0; i < 1000; i++) { - minHandles.Add(hlsfAllocator.Alloc(64)); - } - foreach (HybridLayerSegregatedFitAllocationHandle handle in minHandles) { - hlsfAllocator.Free(handle); - } - Console.WriteLine("最小分配测试完成"); - - // 测试最大分配 - Console.WriteLine("测试最大分配 (1024字节)..."); - List maxHandles = new List(); - for (int i = 0; i < 1000; i++) { - maxHandles.Add(hlsfAllocator.Alloc(1024)); - } - foreach (HybridLayerSegregatedFitAllocationHandle handle in maxHandles) { - hlsfAllocator.Free(handle); - } - Console.WriteLine("最大分配测试完成"); - - // 测试混合大小分配 - Console.WriteLine("测试混合大小分配..."); - List mixedHandles = new List(); - uint[] testSizes = { - 64, 128, 256, 512, 1024 - }; - for (int i = 0; i < 2000; i++) - { - uint size = testSizes[i % testSizes.Length]; - mixedHandles.Add(hlsfAllocator.Alloc(size)); - } - foreach (HybridLayerSegregatedFitAllocationHandle handle in mixedHandles) { - hlsfAllocator.Free(handle); - } - Console.WriteLine("混合大小分配测试完成"); - - Console.WriteLine("\n所有测试完成!HLSF分配器表现良好。"); - Console.WriteLine("按任意键退出..."); - Console.ReadKey(); - /* } catch (Exception ex) { @@ -174,16 +84,16 @@ namespace StgSharp World.WriteLog($"{ex}", LogType.Error); if( true ) { } Dialogue.PostError( ex ); - /* + /**/ World.Terminate(-1); - /* + /**/ } finally { World.Terminate(0); } - /**/ + /**/ } } -} \ No newline at end of file +}