8

据我了解,Plinq 按核心数决定要打开多少线程(每个线程在不同核心上的线程上)。

__________

  Core 1
  Core 2
  Core 3
  Core 4
___________

因此,如果我有一个 Plinq 任务找到所有前 1000 个素数,Plink 将打开一个新任务Thread on each Core以最大限度地提高效率。

所以在这里,每个核心将运行在 1000/4 个数字上,即寻找素数的逻辑。

但是,我读过IO应该使用类似的阻塞操作,WithDegreeOfParallelism这样 cpu 就不会认为这是一个密集的 cpu 操作,并且它允许使用more线程而不是cores.

问题 :

1)它准确吗?我理解正确吗?

2)如果我WithDegreeOfParallelism (7)这样设置,它肯定会使用所有 4 个核心,但其他 3 个呢?(7-4) 他们会跑到哪里去?在哪个核心/秒上?

4

1 回答 1

13

首先,.Net 不会选择哪个内核执行哪个线程,操作系统会选择。如果系统上没有运行其他 CPU 密集型应用程序,您可以预期每个线程将在单独的内核上执行。但是,如果有其他应用程序,操作系统可能会决定在单个内核上运行所有线程,并在它们之间切换。

它甚至比这更复杂。线程通常不在单个内核上运行,操作系统一直在将其从内核切换到内核。例如,看一下任务管理器中的以下屏幕截图,它显示了单线程 CPU 密集型应用程序的执行。

任务管理器 CPU 使用率截图

您会注意到单线程在我的所有 4 个内核上执行,并且在它运行的几秒钟内使用了每个内核的大约 25%。

.Net 不知道您计算机的 CPU 使用率,因此它假定执行 CPU 密集型工作的最佳线程数与内核数相同。

我不知道 PLINQ 究竟是如何工作的,但我不希望在您的示例中每个内核都能准确生成 1000/4 素数。如果一个线程已经产生了它的素数份额,而另一个线程还没有完成,那么让第一个线程保持空闲是没有效率的。

是的,对于 IO 操作,最佳线程数不取决于内核数,因此您应该手动设置并行度。(不要忘记最佳线程数可能是 1;硬盘在顺序读取时最快,而不是在多个文件之间来回查找。)

如果你设置WithDegreeOfParallelism(7)它肯定会使用 7 个线程(同样,不能保证核心数量)。操作系统将决定如何在您的 4 个内核上运行这 7 个线程。如果所有这些线程都是 CPU 密集型的,那么它很可能会为每个线程分配 4/7 ≈ 57 % 的内核。如果它们是 IO 绑定的,它将在任何可用的内核上执行刚刚唤醒(未阻塞)的线程的代码。

并且WithDegreeOfParallelism()确实设置了线程的确切数量,而不是它们的最大数量,请参见 Stephen Toub's ParallelOptions.MaxDegreeOfParallelismvs PLINQ'sWithDegreeOfParallelism

于 2012-08-18T18:42:39.903 回答