buffer op brief ok, but blocks on unkown reason
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user