Arrange code structure. Introduce dynamic scheduler and multi leader.

This commit is contained in:
Youmu Liu
2025-10-21 18:06:20 +08:00
parent b26ec45433
commit 91a0add1d1
3 changed files with 40 additions and 64 deletions
@@ -38,18 +38,15 @@ namespace StgSharp.Mathematics.Numeric
public unsafe class MatrixParallelWrap
{
private readonly Queue<IntPtr>[] _cache;
private readonly Handle[] _resetHandle;
private readonly Thread[] _threads;
public MatrixParallelWrap(int id, int wrapSize)
{
ID = id;
_cache = new Queue<IntPtr>[wrapSize];
_threads = new Thread[wrapSize];
for (int i = 0; i < wrapSize; i++)
{
_cache[i] = new Queue<IntPtr>(8);
_threads[i] = new Thread(MatrixParallelWorker)
{
IsBackground = true,
@@ -70,21 +67,6 @@ namespace StgSharp.Mathematics.Numeric
internal ManualResetEventSlim SchedulerReset { get; } = new(false);
public Span<IntPtr> EnqueuePackage(Span<IntPtr> packageSpan)
{
int idx = 0;
for (; idx < _cache.Length; idx++) {
_cache[idx].Enqueue(packageSpan[idx]);
}
return packageSpan[idx..];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Queue<IntPtr> GetWorkerTaskQueue(int idInWrap)
{
return _cache[idInWrap];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetAllWorker()
{
@@ -104,6 +86,8 @@ namespace StgSharp.Mathematics.Numeric
/// </summary>
public int Role { get; internal set; }
public Queue<IntPtr> 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<IntPtr> 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<IntPtr> 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);
}