wrap scheduler is ok after test

This commit is contained in:
Youmu Liu
2025-09-15 13:39:47 +08:00
parent 0a16f8317f
commit c655469f5f
4 changed files with 116 additions and 4 deletions
@@ -39,7 +39,7 @@ using System.Threading.Tasks;
namespace StgSharp.Mathematics namespace StgSharp.Mathematics
{ {
internal static partial class MatrixParallel public static partial class MatrixParallel
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -33,6 +33,7 @@ using StgSharp.HighPerformance.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO.Pipes; using System.IO.Pipes;
using System.Linq; using System.Linq;
@@ -63,7 +64,7 @@ namespace StgSharp.Mathematics
* we allow each wrap to contain either 3 or 4 threads, providing flexibility while maintaining efficiency. * we allow each wrap to contain either 3 or 4 threads, providing flexibility while maintaining efficiency.
*/ */
internal static partial class MatrixParallel public static partial class MatrixParallel
{ {
private static Thread[] _threads; private static Thread[] _threads;
@@ -81,7 +82,9 @@ namespace StgSharp.Mathematics
public static bool IsParallelMeaningful { get; } = Environment.ProcessorCount > 6; public static bool IsParallelMeaningful { get; } = Environment.ProcessorCount > 6;
internal static MatrixParallelWrap.Handle LeaderHandle { get; private set; } public static MatrixParallelWrap.Handle LeaderHandle { get; /*private/**/ set; }
private static bool IsInitialized { get; set; } = false;
public static void EndParallel() public static void EndParallel()
{ {
@@ -105,6 +108,9 @@ namespace StgSharp.Mathematics
public static void Init() public static void Init()
{ {
if (IsInitialized) {
return;
}
int count = Environment.ProcessorCount - 4; int count = Environment.ProcessorCount - 4;
count = count == 5 ? 4 : count; count = count == 5 ? 4 : count;
_threads = new Thread[count]; _threads = new Thread[count];
@@ -128,6 +134,7 @@ namespace StgSharp.Mathematics
} }
} }
LeaderHandle = new MatrixParallelWrap.Handle(0, _wraps[0]); LeaderHandle = new MatrixParallelWrap.Handle(0, _wraps[0]);
IsInitialized = true;
} }
public static void LaunchParallel(SleepMode afterWork) public static void LaunchParallel(SleepMode afterWork)
@@ -144,8 +151,15 @@ namespace StgSharp.Mathematics
public static void PublishTask() { } public static void PublishTask() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ResetThreadCount()
{
RemainThreadCount = _threads.Length;
}
public static void SetAllWrap() public static void SetAllWrap()
{ {
ResetThreadCount();
foreach (MatrixParallelWrap item in _wraps) { foreach (MatrixParallelWrap item in _wraps) {
_ = item.SchedulerReset.Set(); _ = item.SchedulerReset.Set();
} }
@@ -234,12 +248,15 @@ namespace StgSharp.Mathematics
int inWrapIndex = handle.InWrapIndex; int inWrapIndex = handle.InWrapIndex;
Thread self = Thread.CurrentThread; Thread self = Thread.CurrentThread;
AutoResetEvent reset = wrap.GetWorkerResetEvent(inWrapIndex); AutoResetEvent reset = wrap.GetWorkerResetEvent(inWrapIndex);
Console.WriteLine($"[Worker] 线程 {self.Name} 启动,Wrap ID: {wrap.ID}, 索引: {inWrapIndex}");
do do
{ {
_ = reset.WaitOne(); _ = reset.WaitOne();
Console.WriteLine($"[Worker] 线程 {self.Name} 收到任务信号,开始执行");
self.Priority = ThreadPriority.Highest; self.Priority = ThreadPriority.Highest;
ExecuteTaskPackage(wrap.GetWorkerTaskQueue(inWrapIndex)); ExecuteTaskPackage(wrap.GetWorkerTaskQueue(inWrapIndex));
_ = Interlocked.Decrement(ref RemainThreadCount); int remainCount = Interlocked.Decrement(ref RemainThreadCount);
Console.WriteLine($"[Worker] 线程 {self.Name} 完成任务,剩余线程数: {remainCount--}");
self.Priority = _AfterWork; self.Priority = _AfterWork;
} while (true); } while (true);
} }
@@ -252,14 +269,19 @@ namespace StgSharp.Mathematics
Queue<IntPtr> taskQueue = wrap.GetWorkerTaskQueue(inWrapIndex); Queue<IntPtr> taskQueue = wrap.GetWorkerTaskQueue(inWrapIndex);
AutoResetEvent resetEvent = wrap.SchedulerReset; AutoResetEvent resetEvent = wrap.SchedulerReset;
Thread self = Thread.CurrentThread; Thread self = Thread.CurrentThread;
Console.WriteLine($"[Scheduler] 调度器线程 {self.Name} 启动,Wrap ID: {wrap.ID}, 索引: {inWrapIndex}");
do do
{ {
_ = resetEvent.WaitOne(); _ = resetEvent.WaitOne();
Console.WriteLine($"[Scheduler] 调度器线程 {self.Name} 收到调度信号,开始分发任务");
self.Priority = ThreadPriority.Highest; self.Priority = ThreadPriority.Highest;
// TODO task publication to worker in wrap // TODO task publication to worker in wrap
wrap.SetAllWorker(); wrap.SetAllWorker();
Console.WriteLine($"[Scheduler] 调度器线程 {self.Name} 已通知所有工作线程");
ExecuteTaskPackage(taskQueue); ExecuteTaskPackage(taskQueue);
int remain = Interlocked.Decrement(ref RemainThreadCount);
Console.WriteLine($"[Scheduler] 调度器线程 {self.Name} 完成调度任务,剩余线程数: {remain--}");
self.Priority = _AfterWork; self.Priority = _AfterWork;
} while (true); } while (true);
} }
+87
View File
@@ -0,0 +1,87 @@
using StgSharp.Mathematics;
using System;
using System.Threading;
namespace StgSharp
{
/// <summary>
/// 矩阵计算并发调度器线程调度测试 修复的问题: 1. 添加了ResetThreadCount()方法,在每轮任务调度前重置线程计数 2.
/// 调度器线程不再递减RemainThreadCount,只有工作线程才递减 3. 改进了控制台输出,显示更清晰的线程活动信息 使用方法:在Program.cs的Main方法中调用
/// MatrixParallelThreadTest.TestMatrixParallelThreadScheduling(); 或者通过命令行运行程序时调用此方法
/// </summary>
public class MatrixParallelThreadTest
{
/// <summary>
/// 测试矩阵并行计算线程调度
/// </summary>
public static void TestMatrixParallelThreadScheduling()
{
Console.WriteLine("=== 矩阵并行计算线程调度测试开始 ===");
Console.WriteLine($"CPU核心数: {Environment.ProcessorCount}");
Console.WriteLine($"支持并行计算: {MatrixParallel.SupportParallel}");
Console.WriteLine($"并行计算有意义: {MatrixParallel.IsParallelMeaningful}");
if (!MatrixParallel.SupportParallel)
{
Console.WriteLine("当前系统不支持并行计算,跳过测试");
return;
}
try
{
// 初始化矩阵并行计算系统
Console.WriteLine("\n--- 初始化矩阵并行计算系统 ---");
MatrixParallel.Init();
Console.WriteLine("矩阵并行计算系统初始化完成");
// 启动并行计算
Console.WriteLine("\n--- 启动并行计算 ---");
MatrixParallel.LaunchParallel(SleepMode.QuickWakeup);
Console.WriteLine("并行计算已启动");
// 获取领导者句柄
MatrixParallel.MatrixParallelWrap.Handle leaderHandle = MatrixParallel.LeaderHandle;
Console.WriteLine($"领导者句柄获取成功: Wrap ID {leaderHandle.Wrap.ID}");
// 模拟一些任务调度
Console.WriteLine("\n--- 开始模拟任务调度 ---");
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"\n第 {i + 1} 轮任务调度:");
// 开始并行计算
MatrixParallel.LeadParallel();
Console.WriteLine("已获取并行计算锁");
// 设置所有Wrap
MatrixParallel.SetAllWrap();
Console.WriteLine("已通知所有Wrap开始工作");
// 发布任务(当前为空实现)
MatrixParallel.PublishTask();
Console.WriteLine("任务发布完成");
// 等待一段时间让线程执行
Thread.Sleep(100);
// 结束并行计算
MatrixParallel.EndParallel();
Console.WriteLine("已释放并行计算锁");
// 等待一段时间再进行下一轮
Thread.Sleep(200);
}
Console.WriteLine("\n--- 测试完成 ---");
Console.WriteLine("线程调度测试已成功完成,请观察上述输出中的线程活动信息");
}
catch (Exception ex)
{
Console.WriteLine($"测试过程中发生异常: {ex.Message}");
Console.WriteLine($"异常详情: {ex}");
}
}
}
}
+3
View File
@@ -61,6 +61,8 @@ namespace StgSharp
/**/ /**/
try try
{ {
MatrixParallelThreadTest.TestMatrixParallelThreadScheduling();
/*
HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400); HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400);
Matrix<float> m = Matrix<float>.FromHlsf(400, 200, hlsf); Matrix<float> m = Matrix<float>.FromHlsf(400, 200, hlsf);
@@ -77,6 +79,7 @@ namespace StgSharp
ii++; ii++;
Console.WriteLine($"============================{ii}"); Console.WriteLine($"============================{ii}");
} }
/**/
} }
catch (Exception ex) catch (Exception ex)
{ {