我正在使用 parallel.for 设置:
Parallel.For(0, 4, new ParallelOptions { MaxDegreeOfParallelism = 4 }, j =>
我期待它创建 4 个工作线程,但是并发可视化器仅显示正在使用 3 个工作线程。我尝试使用最大并行度和处理器亲和度,但是在每种情况下只使用 3 个工作线程,而不是 4 个。为什么会发生这种情况有一个明显的答案吗?干杯
我正在使用 parallel.for 设置:
Parallel.For(0, 4, new ParallelOptions { MaxDegreeOfParallelism = 4 }, j =>
我期待它创建 4 个工作线程,但是并发可视化器仅显示正在使用 3 个工作线程。我尝试使用最大并行度和处理器亲和度,但是在每种情况下只使用 3 个工作线程,而不是 4 个。为什么会发生这种情况有一个明显的答案吗?干杯
正如它所说MaxDegreeOfParallelism
,所以它不会超过这个,但它也不会使用超过认为必要的东西。
这是它在MSDN上所说的:
默认情况下,For 和 ForEach 将使用底层调度程序提供的线程数,因此从默认值更改 MaxDegreeOfParallelism 只会限制将使用多少并发任务。
如前所述,您只能指定最大线程数,而不是实际线程数。如果您有四个可用内核,并且工作负载很重要,那么所有四个都将并行运行,因为您启动的线程For
也用于执行工作项。
此外,Parallel.For
可能会分块您的输入范围。它可能不会用于四个项目,但如果您担心,您可以一次安排 4 个项目Parallel.Invoke()
。
这是设计使然,我不记得我在哪里读到它了,但它使用了下面的线程池,并且它只接受任务,因为有处理器能力这样做。尽管 C# 和 F# 之间存在差异听起来很奇怪。
从理论上讲,它还应该取决于可用的处理器内核。如果只有一个核心,则无需启动多个线程。
如果您想强制它使用 4,您可以编写自己的调度程序。
Parralel.For 不知道你会给它带来多少烦恼,它很灵活,它处理线程队列,并且在运行时它决定了哪些可用的核心从 threadque 接收某个工作线程。核心可能不可用,因为它不仅是您在 Windows 机器上运行的代码。或者一个核心可能仍然忙于你之前给它的工作负载。
这里有更深入的信息http://reedcopsey.com/2010/01/26/parallelism-in-net-part-5-partitioning-of-work/