【问题标题】:Plinq, Cores and WithDegreeOfParallelism?Plinq、Cores 和 WithDegreeOfParallelism?
【发布时间】:2012-08-14 18:35:05
【问题描述】:

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

__________

  Core 1
  Core 2
  Core 3
  Core 4
___________

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

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

但是我读到像IO 这样的阻塞操作应该与WithDegreeOfParallelism 一起使用,这样cpu 就不会认为这是一个密集的cpu 操作,并且它允许使用more 线程而不是@ 987654326@.

问题:

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

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

【问题讨论】:

  • 您可能还想查看 WithExecutionMode。如果 IO 是使并行性成为可能的唯一因素,那么这增加了在检查查询时 plinq 错误调用是否比仅串行处理更好的可能性。相反,如果 plinq 决定,它也有可能是正确的,因此无论有无都值得处理。

标签: c# .net .net-4.0 plinq


【解决方案1】:

首先,.Net 不会选择哪个内核执行哪个线程,操作系统会选择。如果系统上没有运行其他 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 的 ParallelOptions.MaxDegreeOfParallelism vs PLINQ’s WithDegreeOfParallelism

【讨论】:

  • 谢谢斯维克。所以 Plinq 自动在 core 之间划分数据,我不知道多出来的 3 会去哪里。对吧?
  • 不,PLINQ 不对内核做任何事情,只对线程做任何事情。 PLINQ 在 线程 而不是内核之间划分数据。就像我说的,将线程调度到内核是操作系统的工作,而不是 .Net。而且您无法知道任何线程的去向,前 4 和“额外” 3 之间没有区别。
  • 我觉得我理解有点问题:PLINQ doesn't do anything with cores, The OS does....ok。但是当我使用 Plinq 时 - 工作 WILL 会在内核之间分配(假设执行模式 = 并行)...对吗? PLINQ 是一个查询执行引擎,它接受任何 LINQ-to-Objects 或 LINQ-to-XML 查询,并在可用时自动利用多个处理器或内核执行。 msdn.microsoft.com/en-us/magazine/cc163329.aspx
  • 这取决于操作系统和系统中的其他进程。操作系统很可能会在内核之间分配线程的工作,是的。但是,如果有其他 CPU 密集型进程正在运行,您仍然可能无法从并行化中获得任何优势。
  • 奇怪的是:如果我指定WithDegreeOfParallelism,我实际上告诉CPU这不是CPU密集型操作,所以如果我告诉他WithDegreeOfParallelism(10) - 他实际上可以打开所有这10个单核中的线程......对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 2012-01-22
相关资源
最近更新 更多