0

我需要一个并行 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 上下文在一次迭代中使用最大内核在 cpu 上执行内核。其他迭代使用 1-2 个内核来复制缓冲区并将命令发送到设备。当 cpu 被 opencl 使用时,它会使用所有的内核,并且设备无法获得足够的时间来复制缓冲区。设备裂变似乎比我想的解决这个问题更难。

4

1 回答 1

2

Parallel.For 迭代中的不同线程亲和性

问题具有误导性,因为它基于ParallelAPI 意味着多线程的假设。ParallelAPI 确实引用了数据并行处理,但不为调用提供任何保证multiple threads,尤其是对于上面提供的代码,每个线程几乎没有任何工作。

对于ParallelAPI,您可以设置 Max degree of Parallelism,如下所示:

ParallelOptions parallelOption = new ParallelOptions();

parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;

Parallel.For(0, 20, parallelOption, i =>

但这永远不能保证将被调用到并行处理的线程数,因为线程是在运行时使用的,ThreadPoolCLR在运行时根据要处理的工作量决定是否超过one thread处理所需的数量。

在同一个Parallel循环中,您可以尝试以下 print 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表示什么,您是否真的拥有具有这么多处理器的服务器。

编辑:

尝试对您的程序进行以下编辑(基于打印两个线程 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);
});
于 2016-09-16T05:22:51.507 回答