add scheduler method; fixing buffer parallel errors

This commit is contained in:
Youmu Liu
2025-11-19 19:57:29 +08:00
parent 04fc55d31e
commit a29a442723
5 changed files with 84 additions and 6 deletions
@@ -70,9 +70,11 @@ namespace StgSharp.Mathematics.Numeric
{ {
RemainThreadCount = _threads.Count; RemainThreadCount = _threads.Count;
_AfterWork = (ThreadPriority)afterWork; _AfterWork = (ThreadPriority)afterWork;
MatrixParallelThread leader = handle.GetLeader();
foreach (MatrixParallelWrap w in handle.Wraps) { foreach (MatrixParallelWrap w in handle.Wraps) {
w.SetScheduler(); w.SetScheduler();
} }
leader.MatrixParallelLeader();
} }
internal static void Init() internal static void Init()
@@ -97,6 +97,13 @@ namespace StgSharp.Mathematics.Numeric
private bool IsMultithread { get; init; } private bool IsMultithread { get; init; }
public MatrixParallelThread DefineLeader()
{
MatrixParallelThread leader = _threads[1];
leader.Role = 2;
return leader;
}
public void Dispose() public void Dispose()
{ {
if (_disposed) { if (_disposed) {
@@ -37,7 +37,7 @@ using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric namespace StgSharp.Mathematics.Numeric
{ {
public class MatrixParallelThread : IDisposable public partial class MatrixParallelThread : IDisposable
{ {
// Affinity binding info for this thread // Affinity binding info for this thread
@@ -58,6 +58,9 @@ namespace StgSharp.Mathematics.Numeric
_resetEvent = new ManualResetEventSlim(false); _resetEvent = new ManualResetEventSlim(false);
} }
// Global runtime switch: true => UMA/no-affinity; false => NUMA/affinity (auto-detected)
public static bool UseUmaAffinityPath { get; } = DetectUmaAffinityPath();
// ~MatrixComputeThread() // ~MatrixComputeThread()
// { // {
// Dispose(disposing: false); // Dispose(disposing: false);
@@ -135,6 +138,36 @@ namespace StgSharp.Mathematics.Numeric
_resetEvent.Set(); _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) protected virtual void Dispose(bool disposing)
{ {
if (!disposedValue) 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() private unsafe void MatrixParallelWorker()
{ {
// Bind OS-thread affinity once when the worker starts running // Bind OS-thread affinity once when the worker starts running
@@ -312,6 +375,10 @@ namespace StgSharp.Mathematics.Numeric
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
private static extern nuint SetThreadAffinityMask(IntPtr hThread, nuint dwThreadAffinityMask); 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 #elif LINUX
#endif #endif
@@ -69,8 +69,11 @@ namespace StgSharp.Mathematics.Numeric
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetAllWorker() public void SetAllWorker()
{ {
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) { for (int i = _begin; i < _begin + WrapTaskCapacity; i++)
_threads[i].Restart(); {
if (_threads[i].Role != 3) {
_threads[i].Restart();
}
} }
} }
+2 -3
View File
@@ -86,10 +86,9 @@ namespace StgSharp
{ {
Console.WriteLine(ex); Console.WriteLine(ex);
Console.ReadLine(); Console.ReadLine();
/* /**/
World.WriteLog($"{ex}", LogType.Error); World.WriteLog($"{ex}", LogType.Error);
if( true ) { } Dialogue.PostError(ex);
Dialogue.PostError( ex );
/**/ /**/
World.Terminate(-1); World.Terminate(-1);
/**/ /**/