据我所知,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)它们将在哪里运行?在哪个内核上?
发布于 2012-08-19 02:42:40
首先,.Net不会选择哪个内核执行哪个线程,而是由操作系统来选择。如果系统上没有运行其他CPU密集型应用程序,则可以预期每个线程将在单独的核心上执行。但如果有其他应用程序,例如,操作系统可能会决定在单个内核上运行所有线程,并在它们之间进行切换。
它甚至比这更复杂。线程通常不会在单个内核上运行,操作系统会一直在内核之间切换线程。例如,看一下Task Manager中的以下屏幕截图,其中显示了单线程CPU密集型应用程序的执行情况。

您将注意到,单个线程在我的所有4个核心上执行,并且在运行的几秒钟内利用了大约25%的每个核心。
.Net不知道您的计算机的CPU使用情况,因此它假定执行CPU密集型工作的最佳线程数与核心数相同。
我不知道PLINQ到底是如何工作的,但我不希望在你的例子中每个核心都能精确地产生1000/4的质数。如果一个线程已经产生了它的素数份额,而另一个线程还没有完成,那么让第一个线程保持空闲将是无效的。
是的,对于IO操作,最优的线程数量并不依赖于内核的数量,因此您应该手动设置并行度。(不要忘记,线程的最佳数量可能是1;硬盘在顺序读取时速度最快,而不是在许多文件之间来回查找。)
如果你设置了WithDegreeOfParallelism(7),它肯定会使用7个线程(同样,不能保证内核的数量)。操作系统将决定如何在您的4核上运行这7个线程。如果所有这些线程都是CPU密集型的,那么很可能会为每个线程分配大约4/7≈的57 %的内核。如果它们是IO绑定的,它将在任何可用内核上执行刚刚唤醒(未阻塞)的线程的代码。
WithDegreeOfParallelism()确实设置了确切的线程数量,而不是它们的最大数量,参见Stephen Toub的 。
https://stackoverflow.com/questions/12020568
复制相似问题