add scheduler method; fixing buffer parallel errors
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user