add scheduler method; fixing buffer parallel errors
This commit is contained in:
@@ -37,7 +37,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace StgSharp.Mathematics.Numeric
|
||||
{
|
||||
public class MatrixParallelThread : IDisposable
|
||||
public partial class MatrixParallelThread : IDisposable
|
||||
{
|
||||
|
||||
// Affinity binding info for this thread
|
||||
@@ -58,6 +58,9 @@ namespace StgSharp.Mathematics.Numeric
|
||||
_resetEvent = new ManualResetEventSlim(false);
|
||||
}
|
||||
|
||||
// Global runtime switch: true => UMA/no-affinity; false => NUMA/affinity (auto-detected)
|
||||
public static bool UseUmaAffinityPath { get; } = DetectUmaAffinityPath();
|
||||
|
||||
// ~MatrixComputeThread()
|
||||
// {
|
||||
// Dispose(disposing: false);
|
||||
@@ -135,6 +138,36 @@ namespace StgSharp.Mathematics.Numeric
|
||||
_resetEvent.Set();
|
||||
}
|
||||
|
||||
internal void MatrixParallelLeader()
|
||||
{
|
||||
Thread current = Thread.CurrentThread;
|
||||
current.Priority = ThreadPriority.Highest;
|
||||
Thread.Sleep(0);
|
||||
|
||||
#if WINDOWS
|
||||
if (!UseUmaAffinityPath)
|
||||
{
|
||||
// NUMA/affinity path: bind to this thread's reserved mask, then restore
|
||||
nuint previousMask = SetThreadAffinityMask(GetCurrentThread(), _affinity.Mask);
|
||||
bool affinityChanged = previousMask != 0; // nonzero => success
|
||||
ExecuteTaskPackage(Tasks);
|
||||
if (affinityChanged) {
|
||||
_ = SetThreadAffinityMask(GetCurrentThread(), previousMask);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// UMA path: no affinity binding
|
||||
ExecuteTaskPackage(Tasks);
|
||||
}
|
||||
#else
|
||||
// Non-Windows: no affinity control
|
||||
ExecuteTaskPackage(Tasks);
|
||||
#endif
|
||||
|
||||
this.Role = 1;
|
||||
current.Priority = ThreadPriority.Normal;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
@@ -152,6 +185,36 @@ namespace StgSharp.Mathematics.Numeric
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DetectUmaAffinityPath()
|
||||
{
|
||||
#if WINDOWS
|
||||
try
|
||||
{
|
||||
// Quick heuristic: single CPU looks like UMA
|
||||
if (Environment.ProcessorCount <= 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Query NUMA topology: highest node number 0 => single node => UMA
|
||||
uint highest = 0;
|
||||
if (GetNumaHighestNodeNumber(out highest)) {
|
||||
return highest == 0;
|
||||
}
|
||||
|
||||
// If query fails, prefer UMA (safer: no affinity changes)
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
// Non-Windows: treat as UMA (no affinity API available)
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
private unsafe void MatrixParallelWorker()
|
||||
{
|
||||
// Bind OS-thread affinity once when the worker starts running
|
||||
@@ -312,6 +375,10 @@ namespace StgSharp.Mathematics.Numeric
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern nuint SetThreadAffinityMask(IntPtr hThread, nuint dwThreadAffinityMask);
|
||||
|
||||
[LibraryImport("kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static partial bool GetNumaHighestNodeNumber(out uint HighestNodeNumber);
|
||||
|
||||
#elif LINUX
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user