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;
_AfterWork = (ThreadPriority)afterWork;
MatrixParallelThread leader = handle.GetLeader();
foreach (MatrixParallelWrap w in handle.Wraps) {
w.SetScheduler();
}
leader.MatrixParallelLeader();
}
internal static void Init()
@@ -97,6 +97,13 @@ namespace StgSharp.Mathematics.Numeric
private bool IsMultithread { get; init; }
public MatrixParallelThread DefineLeader()
{
MatrixParallelThread leader = _threads[1];
leader.Role = 2;
return leader;
}
public void Dispose()
{
if (_disposed) {
@@ -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
@@ -69,8 +69,11 @@ namespace StgSharp.Mathematics.Numeric
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetAllWorker()
{
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) {
_threads[i].Restart();
for (int i = _begin; i < _begin + WrapTaskCapacity; i++)
{
if (_threads[i].Role != 3) {
_threads[i].Restart();
}
}
}
+2 -3
View File
@@ -86,10 +86,9 @@ namespace StgSharp
{
Console.WriteLine(ex);
Console.ReadLine();
/*
/**/
World.WriteLog($"{ex}", LogType.Error);
if( true ) { }
Dialogue.PostError( ex );
Dialogue.PostError(ex);
/**/
World.Terminate(-1);
/**/