我需要一个并行for循环的迭代来使用7个核心(或远离1个核心),但需要另一个迭代来使用8个(所有)核心并尝试使用下面的代码:
Parallel.For(0,2,i=>{
if(i=0)
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);
if(i==1)
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
Thread.Sleep(25);// to make sure both set their affinities
Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});
这两次迭代输出255。因此,parallel.for循环使用单个线程,或者一个设置也设置其他迭代亲和性。另一个问题是,这是来自对延迟敏感的应用程序,所有这些关联设置都会增加1到15毫秒的延迟。
我是否必须明确使用线程,我应该只设置一次亲和力吗?
编辑:我尝试过线程版,同样的事情发生了。即使有明确的两个线程,都要将255写入控制台。现在看来这个命令是针对一个进程而不是一个线程。
OpenCL上下文在一次迭代中使用max cores来在cpu上执行内核。其他迭代使用1-2个内核来复制缓冲区并将命令发送到设备。当opencl使用cpu时,它使用所有内核并且设备无法获得足够的时间来复制缓冲区。设备裂变似乎比解决这个问题更困难。
答案 0 :(得分:2)
Parallel.For Iterations中的不同线程亲和力
问题具有误导性,因为它基于Parallel
API意味着多个线程的假设。 Parallel
API确实引用了数据并行处理,但没有为调用multiple threads
提供任何保证,特别是对于上面提供的代码,每个线程几乎没有任何工作。
对于Parallel
API,您可以设置最大并行度,如下所示:
ParallelOptions parallelOption = new ParallelOptions();
parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;
Parallel.For(0, 20, parallelOption, i =>
但是这永远不能保证调用并行处理的线程数,因为根据要处理的工作量,ThreadPool
和CLR
在运行时决定使用线程,处理时是否需要one thread
以上。
在同一个Parallel
循环中,您可以尝试以下命令,打印Thread.Current.ManageThreadId
,这将提供一个清晰的想法,关于Parallel
循环中调用的线程数。
我是否必须明确使用线程,我应该只设置一次亲和力吗?
编辑:我尝试过线程版,同样的事情发生了。即使有明确的两个线程,都要将255写入控制台。现在看来这个命令是针对一个进程而不是一个线程。
你可以发布代码,对于多个线程,你可以尝试这样的事情。
Thread[] threadArray = new Thread[2];
threadArray[0] = new Thread(<ThreadDelegate>);
threadArray[1] = new Thread(<ThreadDelegate>);
threadArray[0]. ProcessorAffinity = <Set Processor Affinity>
threadArray[1]. ProcessorAffinity = <Set Processor Affinity>
假设您正确分配了亲和力,您可以打印它们并找到不同的值,请检查以下ProcessThread.ProcessorAffinity。
正如您在上面的链接中看到的另一个注释,您可以根据处理器关联性设置hexadecimal
中的值,不确定值254, 255
表示什么,你真的有服务器吗?许多处理器。
修改强>
尝试对你的程序进行以下编辑,(基于两个Thread ID被打印的事实),现在当图片中的两个线程都有时,它们都得到variable i
的相同值,它们需要一个local variable
以避免关闭问题
Parallel.For(0,2,i=>{
int local = i;
if(local=0)
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);
if(local==1)
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
Thread.Sleep(25);// to make sure both set their affinities
Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});
编辑2:(在实际逻辑执行之前,两个线程都可能会增加,因此大部分都无法正常工作)
int local = -1;
Parallel.For(0,2,i=>{
Interlocked.Increment(ref local);
if(local=0)
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255);
if(local==1)
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254);
Thread.Sleep(25);// to make sure both set their affinities
Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity);
});