我调查并行打破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
循环。
到至多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.For
或Parallel.ForEach
没有Break()
和无后顾之忧。
我的意思是,来吧! 当我做突破(),我想要的东西循环停止。 excactly像我这样经常for循环。
您应该使用Stop()
而不是Break()
如果你想要的东西,以尽快停止。 这不会阻止已经从停止运行的项目,但将不再安排任何项目(包括指数较低或那些先前在枚举比你的当前位置)。
如果中断是从一个平行的第100次迭代for循环迭代称为0-1000
在循环的第100次迭代不一定(实际上可能不是)一个与索引99。
你的线程可以和将在indeterminent顺序运行。 当遇到。BREAK()指令,没有进一步的循环迭代将开始。 究竟何时发生这种情况取决于线程调度的特定运行的具体细节。
我强烈建议阅读
并行编程模式
(从微软免费的PDF)
了解设计决策和设计权衡是走进了TPL。
哪些迭代? 整体迭代计数器? 或每线程?
关闭所有的迭代计划(或者尚未安排)。
记住代表可以用完的顺序,也不能保证该迭代i == 5
将是第六次来执行的,而这是不太可能,除了在极少数情况下的情况。
Q2:我说得对不对?
不,调度也不是那么简单。 而是所有的任务都排队,然后处理队列。 但是,每个线程使用自己的队列中,直到它是空的,当他们从其他线程窃取。 这导致没有办法预测哪个线程将处理什么代表。
如果代表们充分小事就可能会被全部原始调用线程处理(没有其他线程都有机会偷的工作)。
Q3:如何CN真正摆脱当(i == 5)?
如果你想线性(特定)处理,不要同时使用。
该Break
方法是有支持推测执行:尝试不同的方式,一旦任何一个完成停止。