buffer op brief ok, but blocks on unkown reason

This commit is contained in:
Youmu Liu
2025-11-20 16:17:24 +08:00
parent a29a442723
commit c595076005
14 changed files with 434 additions and 325 deletions
@@ -30,6 +30,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.WebSockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
@@ -39,23 +40,22 @@ namespace StgSharp.Mathematics.Numeric
public unsafe class MatrixParallelWrap
{
private readonly MatrixParallelThread[] _threads;
private int _begin;
internal MatrixParallelWrap(MatrixParallelThread[] threads, int begin, int count)
private int _remainThreadCount;
private readonly MatrixParallelHandle _handle;
internal MatrixParallelWrap(MatrixParallelHandle handle, int begin, int count)
{
WrapTaskCapacity = count;
_threads = threads;
_handle = handle;
_begin = begin;
_threads[_begin].Role = 1;
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) {
_threads[i].BindedWrap = this;
for (int i = 0; i < WrapTaskCapacity; i++)
{
Threads[i].Role = MatrixParallelThread.RoleType.Worker;
Threads[i].BindedWrap = this;
}
}
public MatrixParallelWrap()
{
_threads = new MatrixParallelThread[5];
Threads[0].Role = MatrixParallelThread.RoleType.Scheduler;
}
public static SleepMode AfterWork
@@ -66,19 +66,41 @@ namespace StgSharp.Mathematics.Numeric
internal int Magic { get; set; }
private ReadOnlySpan<MatrixParallelThread> Threads
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _handle.Threads[_begin..(_begin + WrapTaskCapacity)];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReportThreadAccomplished()
{
Interlocked.Decrement(ref _remainThreadCount);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReportWrapAccomplished()
{
_handle.ReportWrapAccomplished();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetAllWorker()
{
for (int i = _begin; i < _begin + WrapTaskCapacity; i++)
{
if (_threads[i].Role != 3) {
_threads[i].Restart();
}
for (int i = 1; i < WrapTaskCapacity; i++) {
Threads[i].Restart();
}
}
internal void PublishTaskToWorkers(Queue<IntPtr> tasks)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WaitAllWorker()
{
SpinWait.SpinUntil(() => Volatile.Read(ref _remainThreadCount) == 0);
}
internal void PublishTaskToWorkers()
{
Queue<nint> tasks = WrapTask;
while (tasks.TryDequeue(out nint handle))
{
MatrixParallelTaskPackage* task = (MatrixParallelTaskPackage*)handle;
@@ -100,45 +122,54 @@ namespace StgSharp.Mathematics.Numeric
internal void SetScheduler()
{
MatrixParallelThread thread = _threads[_begin];
MatrixParallelThread thread = Threads[0];
thread.Restart();
_ = Interlocked.Exchange(ref _remainThreadCount, WrapTaskCapacity);
}
private void PublishBufferTaskToWorkers(MatrixParallelTaskPackage* package)
{
long count = Unsafe.As<int, long>(ref package->PrimCount);
long recommendCount = count / 1024;
MatrixParallelThread[] pool = _threads;
ReadOnlySpan<MatrixParallelThread> pool = Threads;
if (pool.Length == 1)
{
pool[0].Tasks.Enqueue((nint)package);
return;
}
long count = Unsafe.As<int, long>(ref package->PrimCount);
long actual = count / pool.Length;
long extra = count % pool.Length;
long offset = 0;
MatrixParallelTaskPackage* current = package;
string msg = $"""
Total: count={count}, length={Threads.Length}{Environment.NewLine}
""";
foreach (MatrixParallelThread thread in pool)
{
long wrapTaskLength = actual;
long ex = extra > 0 ? 1 : 0;
long length = wrapTaskLength + ex;
extra -= ex;
ref long offsetRef = ref Unsafe.As<int, long>(ref current->PrimTileOffset);
offsetRef += offset;
ref long lengthRef = ref Unsafe.As<int, long>(ref current->PrimCount);
lengthRef = wrapTaskLength + ex;
pool[0].Tasks.Enqueue((nint)current);
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 += wrapTaskLength;
offset = length;
}
Console.WriteLine(msg);
}
private void PublishKernelTaskToWorkers(MatrixParallelTaskPackage* package)
{
int primCount = package->PrimCount;
int secCount = package->SecCount;
MatrixParallelThread[] pool = _threads;
ReadOnlySpan<MatrixParallelThread> pool = Threads;
if (pool.Length == 1)
{
@@ -201,31 +232,10 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public class Handle(int inWrapIndex, MatrixParallelWrap wrap)
{
public int InWrapIndex { get; } = inWrapIndex;
/// <summary>
/// Role of the thread in the wrap. 1 is Scheduler, 0 are Workers. 2 is leader, beyond
/// wrap's control.
/// </summary>
public int Role { get; internal set; }
public Queue<IntPtr> TaskCache { get; } = [];
internal ManualResetEventSlim ResetEvent { get; } = new(false);
internal MatrixParallelWrap Wrap { get; } = wrap;
}
#region wrap task
internal unsafe Queue<nint> WrapTask { get; set; } = [];
internal int WrapTaskSliceCount { get; set; }
internal int WrapTaskCapacity { get ; init; }
#endregion