From 28bdc42982db5358d61f4dbdf904dcc3e3ba8895 Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Thu, 20 Nov 2025 17:50:06 +0800 Subject: [PATCH] buffer op and parallel framework is now on full complete --- .../Collections/CapacityFixedStack.cs | 84 +++++++++++-------- .../Mathematics/Linear/Matrix_T.GC.cs | 5 ++ .../Numeric/MatrixParallel.Publish.cs | 9 +- .../Numeric/MatrixParallelThread.cs | 14 +++- .../Numeric/MatrixParallelWrap.cs | 8 +- StgSharpDebug/Program.cs | 19 +++-- 6 files changed, 88 insertions(+), 51 deletions(-) diff --git a/StgSharp.Common/Collections/CapacityFixedStack.cs b/StgSharp.Common/Collections/CapacityFixedStack.cs index 32874bd6..fbfdff05 100644 --- a/StgSharp.Common/Collections/CapacityFixedStack.cs +++ b/StgSharp.Common/Collections/CapacityFixedStack.cs @@ -38,95 +38,109 @@ namespace StgSharp.Collections { private readonly T[] _values; + + // _index points to the next free slot (top empty position). Therefore Count == _index. private int _index; public CapacityFixedStack(int size) { + ArgumentOutOfRangeException.ThrowIfNegative(size); _values = new T[size]; - _index = -1; + _index = 0; // empty stack } public T? First => Volatile.Read(ref _index) > 0 ? _values[0] : default; - public bool IsEmpty => _index == -1; + public bool IsEmpty => Volatile.Read(ref _index) == 0; - public int Count => _index + 1; + public int Count => Volatile.Read(ref _index); public int Capacity => _values.Length; - public ReadOnlySpan AsSpan() - { - return _values.AsSpan(0, _index + 1); - } + public ReadOnlySpan AsSpan() => _values.AsSpan(0, _index); public void Clear() { - Array.Clear(_values, 0, _values.Length); - _index = -1; + if (_index > 0) + { + Array.Clear(_values, 0, _index); + _index = 0; + } } public IEnumerator GetEnumerator() { - for (int i = _index; i >= 0; i--) { + for (int i = _index - 1; i >= 0; i--) { yield return _values[i]; } } public T Peek() { - return _index >= 0 ? _values[_index] : throw new InvalidOperationException("Stack is empty."); + if (_index == 0) { + throw new InvalidOperationException("Stack is empty."); + } + return _values[_index - 1]; } public T Pop() { - if (_index >= 0) - { - T item = _values[_index]; - _index--; - return item; - } else - { + if (_index == 0) { throw new InvalidOperationException("Stack is empty."); } + _index--; + T item = _values[_index]; + _values[_index] = default!; // Clear reference for GC + return item; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T[] PopRange(int count) { - int i = int.Min(count, _index); - _index -= i; - return _values[0..i]; + if (count <= 0 || _index == 0) { + return Array.Empty(); + } + int n = Math.Min(count, _index); + int start = _index - n; + T[] ret = new T[n]; + Array.Copy(_values, start, ret, 0, n); + Array.Clear(_values, start, n); + _index -= n; + return ret; } public void Push(T item) { - _values[++_index] = _index < _values.Length ? item : throw new InvalidOperationException("Stack is full."); + if (_index >= _values.Length) { + throw new InvalidOperationException("Stack is full."); + } + _values[_index] = item; + _index++; } public void PushRange(ReadOnlySpan span) { - if (_index + span.Length >= _values.Length) { + if (span.Length == 0) { + return; + } + if (_index + span.Length > _values.Length) { throw new InvalidOperationException("Not enough space in the stack to push the entire span."); } - - Span sp = _values.AsSpan(_index + 1, span.Length); - span.CopyTo(sp); + span.CopyTo(_values.AsSpan(_index, span.Length)); _index += span.Length; } - public bool TryPop(out T value) + public bool TryPop(out T value) { - if (_index >= 0) - { - T item = _values[_index]; - _index--; - value = item; - return true; - } else + if (_index == 0) { value = default!; return false; } + _index--; + value = _values[_index]; + _values[_index] = default!; + return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -148,7 +162,7 @@ namespace StgSharp.Collections public static CapacityFixedStack Create(ReadOnlySpan values) { CapacityFixedStack stack = new(values.Length); - stack.PushRange(values); + stack.PushRange(values); // Push in order return stack; } diff --git a/StgSharp.Common/Mathematics/Linear/Matrix_T.GC.cs b/StgSharp.Common/Mathematics/Linear/Matrix_T.GC.cs index 57eb48e2..5d971427 100644 --- a/StgSharp.Common/Mathematics/Linear/Matrix_T.GC.cs +++ b/StgSharp.Common/Mathematics/Linear/Matrix_T.GC.cs @@ -92,6 +92,11 @@ namespace StgSharp.Mathematics.Numeric return ref kernel[c, r]; } + ~GCMatrix() + { + NativeMemory.AlignedFree(_buffer); + } + #region enumeration public override unsafe MatrixSegmentEnumeration ColumnEnumeration diff --git a/StgSharp.Mathematics/Numeric/MatrixParallel.Publish.cs b/StgSharp.Mathematics/Numeric/MatrixParallel.Publish.cs index 61bca6fe..437efd04 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallel.Publish.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallel.Publish.cs @@ -67,7 +67,8 @@ namespace StgSharp.Mathematics.Numeric int primCount = package->PrimCount; int secCount = package->SecCount; long count = (long)primCount * secCount; - Console.WriteLine($"amount of kernels is {count}"); + + // Console.WriteLine($"amount of kernels is {count}"); long recommendCount = count / 1024; MatrixParallelThread[] pool = LeadParallel((int)recommendCount); @@ -103,9 +104,9 @@ namespace StgSharp.Mathematics.Numeric lengthRef = length; wrap.WrapTask.Enqueue((nint) current); - Console.WriteLine($"Offset is {offset}"); - Console.WriteLine($"Scheduling {length} kernels into {wrap.WrapTaskCapacity} threads"); - Console.WriteLine(); + // Console.WriteLine($"Offset is {offset}"); + // Console.WriteLine($"Scheduling {length} kernels into {wrap.WrapTaskCapacity} threads"); + // Console.WriteLine(); current = MatrixParallelFactory.FromExistPackage(current); offset += length; } diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs b/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs index 6b801574..85717ef7 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs @@ -253,11 +253,11 @@ namespace StgSharp.Mathematics.Numeric // Console.WriteLine("worker end"); break; case RoleType.Scheduler://scheduler - Console.WriteLine("scheduler start"); + // Console.WriteLine("scheduler start"); BindedWrap.PublishTaskToWorkers(); BindedWrap.SetAllWorker(); - Console.WriteLine("scheduler done"); + // Console.WriteLine("scheduler done"); ExecuteTaskPackage(Tasks); BindedWrap.ReportThreadAccomplished(); BindedWrap.WaitAllWorker(); @@ -416,7 +416,15 @@ namespace StgSharp.Mathematics.Numeric internal Queue Tasks { get; } = []; - public RoleType Role { get; internal set; } + public RoleType Role + { + get; + internal set + { + // Console.WriteLine($"Thread {_managedThread.ManagedThreadId} set to {value}, from thread {Environment.CurrentManagedThreadId}"); + field = value; + } + } public enum RoleType : int { diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs b/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs index 82a10ff0..0bb04ec7 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs @@ -141,9 +141,11 @@ namespace StgSharp.Mathematics.Numeric long offset = 0; MatrixParallelTaskPackage* current = package; + /* string msg = $""" Total: count={count}, length={Threads.Length}{Environment.NewLine} """; + /**/ foreach (MatrixParallelThread thread in pool) { long wrapTaskLength = actual; @@ -155,14 +157,16 @@ namespace StgSharp.Mathematics.Numeric ref long lengthRef = ref Unsafe.As(ref current->PrimCount); lengthRef = length; thread.Tasks.Enqueue((nint)current); + /* msg += $""" Slice to thread: total offset={offsetRef} local offset={offset}, length={lengthRef}{Environment.NewLine} """; - + /**/ current = MatrixParallelFactory.FromExistPackage(current); offset = length; } - Console.WriteLine(msg); + + // Console.WriteLine(msg); } private void PublishKernelTaskToWorkers(MatrixParallelTaskPackage* package) diff --git a/StgSharpDebug/Program.cs b/StgSharpDebug/Program.cs index 143c1a94..0da9b457 100644 --- a/StgSharpDebug/Program.cs +++ b/StgSharpDebug/Program.cs @@ -71,15 +71,20 @@ namespace StgSharp Matrix m = Matrix.FromHlsf(2000, 2000, hlsf); m.Fill(1.0f); - for (int i = 0; i < 20; i++) - { - for (int j = 0; j < 20; j++) { - Console.Write($"{m[i, j]:0.0E+00} \t"); - } - Console.WriteLine(); - } + + Console.WriteLine(); + Console.WriteLine(); Console.WriteLine(); Matrix n = m.Add(m); + for (int i = 0; i < 5; i++) + { + for (int j = 0; j < 2; j++) + { + n = n.Add(m); + Console.WriteLine($"{i} {j}"); + } + GC.Collect(); + } for (int i = 0; i < 20; i++) { for (int j = 0; j < 20; j++) {