Plinq,核心和WithDegreeOfParallelism?

问题描述 投票:8回答:1

据我所知,Plinq通过核心数来决定打开多少个线程(每个线程在不同的核心上)。

__________

  Core 1
  Core 2
  Core 3
  Core 4
___________

所以,如果我有一个Plinq任务,要找到所有前1000个素数,Plink将打开一个新的线程。Thread on each Core 以求效率最大化。

所以在这里,每个核心将运行在10004个数上,寻找质数的逻辑。

然而,我读到一个阻塞操作,如 IO 应与 WithDegreeOfParallelism 这样cpu就不会认为这是一个密集型的cpu操作,并允许它使用 more 线程比 cores.

问题:

1)是否准确?我的理解是否正确?

2)如果我设置 WithDegreeOfParallelism (7) 所以它肯定会使用所有4个核心,但其他3个呢?(7-4)它们会在哪里运行?在哪些核心上?

c# .net .net-4.0 plinq
1个回答
13
投票

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

而且比这更复杂。一个线程通常不会运行在一个核上,操作系统会一直在核与核之间切换。例如,看看下面这张来自任务管理器的截图,它显示了一个单线程CPU密集型应用程序的执行情况。

Task Manager CPU usage screenshot

你会注意到,这个单线程在我的4个核心上都执行了,并且在运行的几秒钟内利用了每个核心的大约25%。

.Net对你的计算机的CPU使用情况一无所知,所以它假设做CPU密集型工作的最佳线程数与核心数相同。

我不知道PLINQ到底是如何工作的,但我不会期望在你的例子中每个核心都能准确地产生10004个质数。如果一个线程已经产生了它应得的质数,而另一个线程还没有完成,那么让第一个线程保持空闲状态就不是很有效率。

是的,对于IO操作,最佳的线程数并不取决于核数,所以你应该手动设置并行度。(别忘了,最佳线程数可能是1,硬盘在顺序读取时是最快的,而不是在许多文件之间来回寻找)。

如果你设置了 WithDegreeOfParallelism(7) 它一定会用7 线程 同样,也不能保证核心数量)。操作系统将决定如何在你的4个核心上运行这7个线程,如果这些线程都是CPU密集型的,它很可能会给每个线程47≈57%的核心。如果这些线程都是CPU密集型的,它很可能会给每个线程47%≈57%的核心。如果它们是IO绑定的,它将在任何一个刚刚可用的核心上执行刚刚唤醒(解封)的线程的代码。

WithDegreeOfParallelism() 确实设置了确切的线程数,而不是最大的线程数,见Stephen Toub的 ParallelOptions.MaxDegreeOfParallelism 与PLINQ的 WithDegreeOfParallelism.

© www.soinside.com 2019 - 2024. All rights reserved.