据我了解,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)他们将在哪里运行?在哪个核心上? 最佳答案
首先,.Net不会选择操作系统执行哪个线程来执行哪个线程。如果系统上没有其他正在运行的CPU密集型应用程序,则可以预期每个线程将在单独的内核上执行。但是,如果有其他应用程序,则操作系统可能会决定例如在单个内核上运行所有线程,并在它们之间进行切换。
而且甚至比这更复杂。线程通常不在单个内核上运行,操作系统会一直在一个内核之间切换。例如,查看下面的任务管理器屏幕快照,该屏幕快照显示了单线程CPU密集型应用程序的执行情况。
您会注意到,单线程在我的所有4个内核上执行,并在运行的几秒钟内利用了每个内核的大约25%。
.Net不了解您计算机的CPU使用情况,因此假定进行CPU密集型工作的最佳线程数与内核数相同。
我不知道PLINQ到底是如何工作的,但是我不希望每个内核在您的示例中都能产生1000/4个素数。如果一个线程已经产生了它的质数份额,而另一个线程还没有完成,那么让第一个线程保持空闲状态将没有效率。
是的,通过IO操作,最佳线程数不取决于内核数,因此您应该手动设置并行度。 (不要忘记最佳线程数可能是1;硬盘是最快的连续读取方式,而不是在许多文件之间来回搜索。)
如果设置WithDegreeOfParallelism(7)
,它将肯定使用7个线程(同样,不能保证内核数量)。操作系统将决定如何在4个内核上运行这7个线程。如果所有这些线程都是CPU密集型的,则很可能会为每个线程提供大约4/7≈57%的内核资源。如果它们是IO绑定(bind)的,它将在刚刚可用的任何内核上为刚刚唤醒(无阻塞)的线程执行代码。WithDegreeOfParallelism()
确实设置了确切的线程数,而不是最大线程数,请参见Stephen Toub的 ParallelOptions.MaxDegreeOfParallelism
vs PLINQ’s WithDegreeOfParallelism
。
关于c# - 是Plinq,Cores和WithDegreeOfParallelism?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12020568/