Parallel.For and Break() misunderstanding?

2019-08-01 06:30发布

我调查并行打破For循环。

看完这个和这个我还是有一个问题:

我期望这样的代码:

 Parallel.For(0, 10, (i,state) =>  
     { 
                Console.WriteLine(i); if (i == 5) state.Break(); 
     }

至多 6个号码(0..6)的产量。 他不仅没有这样做,但有不同的结果长度:

02351486
013542
0135642

很烦人。 (其中,到底是分段(){5之后}此处??)

所以,我看着MSDN

休息可以被用来传达到当前迭代之后没有其他迭代需要运行的循环。 如果中断是从0并行for循环迭代的迭代100叫1000,所有迭代小于100仍应运行,但是从101〜1000迭代是没有必要的。

Quesion#1:

哪些迭代? 整体迭代计数器? 或每线程? 我敢肯定它是每个线程。 请批准。

问题2 :

让我们假设我们正在使用并行+范围分区(由于元件之间没有CPU成本变化),所以它划分线程之间的数据。 因此,如果我们有4个核心(以及它们之间的完美师):

core #1 got 0..250
core #2 got 251..500
core #3 got 501..750
core #4 got 751..1000

所以在螺纹core #1将满足value=100的某个时候和将断裂。 这将是他的迭代次数100 。 但在线程core #4得到了更多的广达和他的900了。 他是远远超出他的100'th迭代。 他可是没有少指数100被停止! - 所以,他会告诉他们。

我对吗 ? 是为什么我得到在我的例子超过5元的原因是什么?

问题3:

如何CN我真正突破的时候(i == 5)

PS

我的意思是,来吧! 当我做Break()我想要的东西循环停止。 excactly像我这样经常For循环。

Answer 1:

到至多6个号码(0..6)的产量。

问题是,这将不会在6号产生

会发生什么事是,当你打一个循环为5的指数,您发送的“破发”的请求。 Break()会导致循环到不再过程中的任何值>5 ,但过程的所有值<5

然而,已经开始的任何值大于5仍然会得到处理。 由于各项指标并行运行,他们不再订购,让你得到一些地方值的各种运行>5 (如在你的例子8)仍在执行。

哪些迭代? 整体迭代计数器? 或每线程? 我敢肯定它是每个线程。 请批准。

这是被传递到的Parallel.For索引。 打破()不会阻止物品被处理,但提供的所有项目多达100个得到处理的保证,但上述100个项目可能会或可能不会进行处理。

我对吗 ? 是为什么我得到在我的例子超过5元的原因是什么?

是。 如果你使用一个分区像你所展示的,只要你调用Break()超越了一个项目,你打破将不再获得计划。 然而,项目(这是整个分区 )已计划将得到完全处理。 在你的榜样,这意味着你可能总是处理所有的1000个项目。

我怎样才能真正摆脱当(i == 5)?

你是 - 但是当你在并行运行,事情的变化。 什么是这里的实际目标是什么? 如果你只想要处理的前6项(0-5),您应通过LINQ查询或类似的通过他们循环之前限制的项目。 然后,您可以处理在6个项目Parallel.ForParallel.ForEach没有Break()和无后顾之忧。

我的意思是,来吧! 当我做突破(),我想要的东西循环停止。 excactly像我这样经常for循环。

您应该使用Stop()而不是Break()如果你想要的东西,以尽快停止。 这不会阻止已经从停止运行的项目,但将不再安排任何项目(包括指数较低或那些先前在枚举比你的当前位置)。



Answer 2:

如果中断是从一个平行的第100次迭代for循环迭代称为0-1000

在循环的第100次迭代不一定(实际上可能不是)一个与索引99。

你的线程可以和将在indeterminent顺序运行。 当遇到。BREAK()指令,没有进一步的循环迭代将开始。 究竟何时发生这种情况取决于线程调度的特定运行的具体细节。

我强烈建议阅读

并行编程模式

(从微软免费的PDF)

了解设计决策和设计权衡是走进了TPL。



Answer 3:

哪些迭代? 整体迭代计数器? 或每线程?

关闭所有的迭代计划(或者尚未安排)。

记住代表可以用完的顺序,也不能保证该迭代i == 5将是第六次来执行的,而这是不太可能,除了在极少数情况下的情况。

Q2:我说得对不对?

不,调度也不是那么简单。 而是所有的任务都排队,然后处理队列。 但是,每个线程使用自己的队列中,直到它是空的,当他们从其他线程窃取。 这导致没有办法预测哪个线程将处理什么代表。

如果代表们充分小事就可能会被全部原始调用线程处理(没有其他线程都有机会偷的工作)。

Q3:如何CN真正摆脱当(i == 5)?

如果你想线性(特定)处理,不要同时使用。

Break方法是有支持推测执行:尝试不同的方式,一旦任何一个完成停止。



文章来源: Parallel.For and Break() misunderstanding?