Parallel.For 次迭代中的不同线程关联

Different thread affinities in Parallel.For Iterations

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

Different thread affinities in Parallel.For Iterations

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

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

ParallelOptions parallelOption = new ParallelOptions();

parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount;

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

但这永远不能保证调用并行处理的线程数,因为线程是从 ThreadPool 开始使用的,而 CLR 在 运行 时间决定,基于要处理的工作量,是否需要处理超过 one thread

在同一个 Parallel 循环中,您可以尝试以下操作,打印 Thread.Current.ManageThreadId,这将提供关于 Parallel 循环中调用的线程数的清晰思路。

Do I have to use threads explicitly and should I set affinities only once?

Edit: I tried threaded version, same thing happens. Even with explicit two threads, both writing 255 to console. Now it seems this command is for a process not a thread.

你能post多线程的代码吗,你能试试这样吗

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

另一个注意事项,如您在上面的 link 中看到的,您可以根据处理器亲和力设置 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);
});