Switch matrix parallel to task stealing, type and wrap are refacored, thread execution core has not yet

This commit is contained in:
Youmu Liu
2026-02-24 15:12:23 +08:00
parent d99c1e3aa6
commit d62e59cb93
21 changed files with 1000 additions and 965 deletions
@@ -46,20 +46,22 @@ namespace StgSharp.Mathematics.Numeric
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe MatrixParallelHandle ScheduleTask(MatrixParallelTaskPackage* package)
internal static unsafe MatrixParallelWrap ScheduleTask(
MatrixParallelTaskPackage* package
)
{
MatrixParallelTaskPackage* nonGeneric = package;
switch (nonGeneric->ComputeMode.OperationStyle)
switch (package->ComputeMode.OperationStyle)
{
case MatrixIndexStyle.BUFFER_INDEX:
return ScheduleBufferTask(nonGeneric);
return ScheduleBufferTask(package);
default:
throw new InvalidOperationException($"Unknown mode {nonGeneric->ComputeMode.OperationStyle}.");
throw new InvalidOperationException($"Unknown mode {package->ComputeMode.OperationStyle}.");
}
}
private static unsafe MatrixParallelHandle ScheduleBufferTask(
MatrixParallelTaskPackage* package)
private static unsafe MatrixParallelWrap ScheduleBufferTask(
MatrixParallelTaskPackage* package
)
{
int primCount = package->PrimCount;
int secCount = package->SecCount;
@@ -69,44 +71,10 @@ namespace StgSharp.Mathematics.Numeric
long recommendCount = count / 1024;
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
MatrixParallelHandle handle = new MatrixParallelHandle(pool);
if (handle.Wraps.Length == 1)
{
// Console.WriteLine($"Scheduling into {pool.Length} threads.");
ref long offsetRef = ref Unsafe.As<int, long>(ref package->PrimTileOffset);
offsetRef = 0;
ref long lengthRef = ref Unsafe.As<int, long>(ref package->PrimCount);
lengthRef = count;
handle.Wraps[0].WrapTask.Enqueue((nint)package);
MatrixParallelWrap handle = new MatrixParallelWrap(pool);
// Console.WriteLine($"Scheduling {count} kernels into thread");
return handle;
}
long actual = count / pool.Length;
long extra = count % pool.Length;
long offset = 0;
MatrixParallelTaskPackage* current = package;
// Console.WriteLine($"Scheduling into {pool.Length} threads.");
foreach (MatrixParallelWrap wrap in handle.Wraps)
{
long wrapTaskLength = actual * wrap.WrapTaskCapacity;
long ex = Math.Min(extra, wrap.WrapTaskCapacity);
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 = length;
wrap.WrapTask.Enqueue((nint) current);
// Console.WriteLine($"Offset is {offset}");
// Console.WriteLine($"Scheduling {length} kernels into {wrap.WrapTaskCapacity} threads");
// Console.WriteLine();
current = MatrixParallelFactory.FromExistPackage(current);
offset += length;
}
// TODO set parallel queue for handle
handle.TaskQueue = MatrixParallelQueue.Rent(package);
return handle;
}