Tpl
和Plinq
自动将工作分配给线程(在核心/s.{那么,如果是#threads> #cores
,>1个线程将运行在同一个内核上。( })
但是,假设我有MyMethod1(){..}
和MyMethod2(){..}
,我需要确保(!)每个人都会在不同的核心上运行!(例如密集计算)
我找到的最接近的解决方案是Plinq的.WithExecutionMode (ParallelExecutionMode.ForceParallelism)
但是,对于不同的情况,Plinq可能会认为,与parallel.Also相比,按顺序执行更好,我不使用Plinq。我只有两个方法,需要运行在一个不同的核心。
我该怎么做呢?
附注:这里有一个建议使用TaskCreationOptions.LongRunning
的答案,但它只是向TaskScheduler暗示,它应该更积极地创建线程池线程。但这些线程可以在同一个核心上。我的处境要求他们处于不同的核心。
谢谢。
发布于 2013-03-30 05:11:27
要做到这一点,需要分解几个抽象层,在此之前,我建议进行相当多的分析,以确定这样做比让框架处理资源分配更好。我有点怀疑(虽然我不能说我分析过)。
您需要做的第一件事是确保在不同的托管线程上执行两个Task
。因为这是试图断言对框架处理的东西的手动控制,因此要确定这是您需要编写自己的TaskScheduler
的情况。但是,实际上您可以通过指定TaskCreationOptions.LongRunning
标志来实现这一点。至少在当前桌面CLR上,这将始终创建一个新线程。但这只是个暗示,就API而言。
下一个要打破的抽象是托管和原生线程的抽象。每个方法都应该包装在一个螺纹亲和力块中。允许框架切换运行托管线程的物理线程。因为处理器关联是一个本机线程操作,所以您必须告诉框架不要这样做。
接下来,您需要获得对应于当前托管线程的本机线程。在每个方法中,在调用BeginThreadAffinity
之后,通过p/invoke调用GetCurrentThreadId来获取本机线程。
现在,您可以在本机或托管域中完成其余的操作,但我将假设您希望在.NET中这样做。
Thread.BeginThreadAffinity();
int threadId = GetCurrentThreadId();
Process proc = Process.GetCurrentProcess();
ProcessThread procThread = proc.Threads.Cast<ProcessThread>().Single(
pt => pt.Id == threadId
);
procThread.ProcessorAffinity = new IntPtr(0x01);
//
// work
//
procThread.ProcessorAffinity = new IntPtr(0xFFFF);
Thread.EndThreadAffinity()
https://stackoverflow.com/questions/15718529
复制相似问题