并行中的不同线程关联。对于迭代

时间:2016-09-16 03:12:16

标签: c# multithreading affinity parallel-for

我需要一个并行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时,它使用所有内核并且设备无法获得足够的时间来复制缓冲区。设备裂变似乎比解决这个问题更困难。

1 个答案:

答案 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 =>

但是这永远不能保证调用并行处理的线程数,因为根据要处理的工作量,ThreadPoolCLR在运行时决定使用线程,处理时是否需要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);
});