强制任务到不同的核心?

TplPlinq自动将工作分配给线程(在核心/ s … { 好吧,如果#threads> #cores那么,> 1个线程将在同一个核心上运行。 })。

但是,假设我有MyMethod1(){..}MyMethod2(){..} ,我需要确保 (!)每个都运行在不同的核心上! (例如密集计算)

我找到的最近的解决方案是Plinq的.WithExecutionMode (ParallelExecutionMode.ForceParallelism)

但这是针对一种不同的情况,Plinq可能会认为按顺序而不是平行进行更好。同时,我不使用Plinq。 我只有2种方法需要在不同的核心上运行。

我该怎么做 ?

ps这里有一个答案,建议使用TaskCreationOptions.LongRunning但它只是暗示TaskScheduler它应该更积极地创建线程池线程。 但是那些线程可以在同一个核心上。 我的情况要求他们处于不同的核心。

谢谢。

要做到这一点,需要分解几个抽象层,在做之前我建议做一些分析,以确保这样做比使框架处理资源分配更好。 我有点怀疑(虽然我不能说我已经分析了它)。

您需要做的第一件事是确保您的两个Task在不同的托管线程上执行。 因为这是试图对框架处理的东西进行手动控制,以确保在这种情况下你需要编写自己的TaskScheduler 。 但是,实际上,您可以通过指定TaskCreationOptions.LongRunning标志来执行此TaskCreationOptions.LongRunning 。 至少在当前桌面CLR上,它将始终创建一个新线程。 但它只是一个提示,API-wise。

下一个要打破的抽象是托管与本机线程的抽象。 您的每个方法都应该包装在线程关联块中。 允许框架切换运行托管线程的物理线程。 由于处理器关联是本机线程操作,因此您必须告诉框架不要这样做。

接下来,您需要获取与当前托管线程对应的本机线程。 在每个方法中,在调用BeginThreadAffinity ,通过p / invoke调用GetCurrentThreadId来获取本机线程。

现在你可以在本地或托管领域完成其余的工作,但我认为你想在.NET中完成它。 在这种情况下,获取与本机线程对应的ProcessThread对象,您可以从那里设置处理器关联或理想处理器 :

 Thread.BeginThreadAffinity(); int threadId = GetCurrentThreadId(); Process proc = Process.GetCurrentProcess(); ProcessThread procThread = proc.Threads.Cast().Single( pt => pt.Id == threadId ); procThread.ProcessorAffinity = new IntPtr(0x01); // // work // procThread.ProcessorAffinity = new IntPtr(0xFFFF); Thread.EndThreadAffinity()