From 91a0add1d16a3c13889436ddd292d02af9fa3d6a Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Tue, 21 Oct 2025 18:06:20 +0800 Subject: [PATCH] Arrange code structure. Introduce dynamic scheduler and multi leader. --- .../Numeric/MatrixParallel.cs | 32 ++++------ .../Numeric/MatrixParallelPool.cs | 10 ++- .../Numeric/MatrixParallelWrap.cs | 62 ++++++------------- 3 files changed, 40 insertions(+), 64 deletions(-) diff --git a/StgSharp.Mathematics/Numeric/MatrixParallel.cs b/StgSharp.Mathematics/Numeric/MatrixParallel.cs index 73664238..1f97cbf8 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallel.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallel.cs @@ -81,8 +81,6 @@ namespace StgSharp.Mathematics.Numeric public static bool IsParallelMeaningful => Environment.ProcessorCount > 6 && IsInitialized; - public static MatrixParallelWrap.Handle LeaderHandle { get; private/**/ set; } - private static bool IsInitialized { get; set; } = false; private static Queue LeaderTask { get; set; } @@ -126,38 +124,34 @@ namespace StgSharp.Mathematics.Numeric { if (count == 3) { - Wraps = [ new MatrixParallelWrap(0, count, true) ]; + Pool = new(3, [ new MatrixParallelWrap(0, count) ]); (LargeWrapCount, SmallWrapCount) = (0, 1); - LeaderHandle = new MatrixParallelWrap.Handle(0, Wraps.Peek()); } else { count = 4; - Wraps = [ new MatrixParallelWrap(0, count, true) ]; + Pool = new(4, [ new MatrixParallelWrap(0, count) ]); (LargeWrapCount, SmallWrapCount) = (1, 0); - LeaderHandle = new MatrixParallelWrap.Handle(0, Wraps.Peek()); } } else if (count == 6) { - Wraps = [ - new MatrixParallelWrap(0, 3, true), - new MatrixParallelWrap(3, 3, false) - ]; + Pool = new(6, [ + new MatrixParallelWrap(0, 3), + new MatrixParallelWrap(3, 3) + ]); (LargeWrapCount, SmallWrapCount) = (0, 2); - LeaderHandle = new MatrixParallelWrap.Handle(0, Wraps.Peek()); } else { (int _3wrap, int _4wrap) = FastDecompose(count); - Wraps = new(_4wrap + _3wrap); + CapacityFixedStack stack = new(_4wrap + _3wrap); int id = 0, idx = 0; for (; idx < _3wrap; idx++, id += 3) { - Wraps.Push(new MatrixParallelWrap(idx, 3, id == 0)); + stack.Push(new MatrixParallelWrap(idx, 3)); } for (; idx < _3wrap + _4wrap; idx++, id += 4) { - Wraps.Push(new MatrixParallelWrap(id, 4, id == 0)); + stack.Push(new MatrixParallelWrap(id, 4)); } - LeaderHandle = new MatrixParallelWrap.Handle(0, Wraps.Peek()); + Pool = new MatrixParallelPool(count, stack); } - LeaderTask = LeaderHandle.Wrap.GetWorkerTaskQueue(0); IsInitialized = true; } @@ -191,18 +185,18 @@ namespace StgSharp.Mathematics.Numeric #region wrap field - private static CapacityFixedStack Wraps; + private static MatrixParallelPool Pool; private static int LargeWrapCount; private static int SmallWrapCount; - public static CapacityFixedStack LeadParallel() + public static MatrixParallelPool LeadParallel() { #if NET9_0_OR_GREATER #else Monitor.Enter(_lock); #endif - return Wraps; + return Pool; } public static void ReleaseParallelLeadership(ref CapacityFixedStack wraps) diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelPool.cs b/StgSharp.Mathematics/Numeric/MatrixParallelPool.cs index afa6a5c6..a2309f31 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelPool.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelPool.cs @@ -49,14 +49,20 @@ namespace StgSharp.Mathematics.Numeric SpareThreads = threadCount; } + internal MatrixParallelPool(int threadCount, CapacityFixedStack wrapSpan) + { + SpareWrap = wrapSpan; + SingleThreadAllocation = new CapacityFixedBag(wrapSpan.Count); + SpareThreads = threadCount; + } + public int SpareThreads { get; set; } internal CapacityFixedBag SingleThreadAllocation { get; set; } internal CapacityFixedStack SpareWrap { get; set; } - public bool TryRequest(out ) - + public bool TryRequestLeaderHandle(out MatrixParallelWrap.Handle handle) { } public bool TryRequestWrap(out MatrixParallelWrap? wrap) { diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs b/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs index b89cad3d..668f5dde 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs @@ -38,18 +38,15 @@ namespace StgSharp.Mathematics.Numeric public unsafe class MatrixParallelWrap { - private readonly Queue[] _cache; private readonly Handle[] _resetHandle; private readonly Thread[] _threads; public MatrixParallelWrap(int id, int wrapSize) { ID = id; - _cache = new Queue[wrapSize]; _threads = new Thread[wrapSize]; for (int i = 0; i < wrapSize; i++) { - _cache[i] = new Queue(8); _threads[i] = new Thread(MatrixParallelWorker) { IsBackground = true, @@ -70,21 +67,6 @@ namespace StgSharp.Mathematics.Numeric internal ManualResetEventSlim SchedulerReset { get; } = new(false); - public Span EnqueuePackage(Span packageSpan) - { - int idx = 0; - for (; idx < _cache.Length; idx++) { - _cache[idx].Enqueue(packageSpan[idx]); - } - return packageSpan[idx..]; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Queue GetWorkerTaskQueue(int idInWrap) - { - return _cache[idInWrap]; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetAllWorker() { @@ -104,6 +86,8 @@ namespace StgSharp.Mathematics.Numeric /// public int Role { get; internal set; } + public Queue TaskCache { get; } = []; + internal ManualResetEventSlim ResetEvent { get; } = new(false); internal MatrixParallelWrap Wrap { get; } = wrap; @@ -138,33 +122,25 @@ namespace StgSharp.Mathematics.Numeric { reset.Wait(); reset.Reset(); + Queue taskQueue = handle.TaskCache; self.Priority = ThreadPriority.Highest; - ExecuteTaskPackage(wrap.GetWorkerTaskQueue(inWrapIndex)); + switch (handle.Role) + { + case 0://worker + // _ = Interlocked.Decrement(ref RemainThreadCount); + ExecuteTaskPackage(handle.TaskCache); + break; + case 1://scheduler + // TODO task publication to worker in wrap + wrap.SetAllWorker(); + ExecuteTaskPackage(taskQueue); - // _ = Interlocked.Decrement(ref RemainThreadCount); - self.Priority = (ThreadPriority)AfterWork; - } while (true); - } - - private static unsafe void MatrixParallelScheduler([AllowNull] object obj) - { - Handle handle = (obj as Handle)!; - MatrixParallelWrap wrap = handle.Wrap; - int inWrapIndex = handle.InWrapIndex; - Queue taskQueue = wrap.GetWorkerTaskQueue(inWrapIndex); - ManualResetEventSlim resetEvent = wrap.SchedulerReset; - Thread self = Thread.CurrentThread; - do - { - resetEvent.Wait(); - resetEvent.Reset(); - self.Priority = ThreadPriority.Highest; - - // TODO task publication to worker in wrap - wrap.SetAllWorker(); - ExecuteTaskPackage(taskQueue); - - // _ = Interlocked.Decrement(ref RemainThreadCount); + break; + case 2://leader, error because leader should be at outer thread but not here + break; + default: + break; + } self.Priority = (ThreadPriority)AfterWork; } while (true); }