的Parallel.For和休息()的误解? [英] Parallel.For and Break() misunderstanding?

查看:187
本文介绍了的Parallel.For和休息()的误解?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我调查并行中断在for循环中。

在阅读和<一href="http://reedcopsey.com/2010/01/22/parallelism-in-net-part-3-imperative-data-parallelism-early-termination/"相对=nofollow>这个我还有一个问题:

我期望这个code:

 的Parallel.For(0,10,(我,州)=&GT;
     {
                Console.WriteLine(ⅰ);如果(ⅰ== 5)state.Break();
     }
 

要在屈服的的6个号码(0..6)。 不仅他没有这样做,但有不同的结果长度:

  02351486
013542
0135642
 

很烦人。 (这里是地狱中断(){后5}在这里?)

所以,我看着MSDN

  

额可以用于通信,以在循环需要被运行当前迭代之后没有其他迭代。   如果中断是从一个100迭代呼吁循环迭代中   平行,从0到1000,所有迭代小于100应该还是   运行,但是从101至1000的迭代是没有必要的。

<大骨节病> Quesion#1:

哪些迭代?整体迭代计数器?或每线程?我是pretty的肯定就是每个线程。请谅解。

<大骨节病>问题2:

让我们假设我们使用并行+范围分区(由于要素之间没有CPU成本的变化),所以它把线程间的数据。因此,如果我们有4个核心(和完善部门都在其中):

 核心#1得到0..250
核心#2得到251..500
核心#3得到501..750
核心#4拿到751..1000
 

所以核心#1线见面会值= 100 的某个时候,将打破。 这将是他的迭代次数 100 。 但在核心#4 线程得到了更多广达和他的 900 现在。他的办法超越的他的 100'th 迭代。 他可是没有少指数100将停止! - ,所以他会告诉他们全部

我说得对不对?就是这就是为什么我在我的例子获得超过5元的原因是什么?

<大骨节病>问题3:

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

P.S。

我的意思是,来吧!当我做中断(),我想要的东西循环停止。 excactly像我这样的普通的循环。

解决方案
  

要产生最多6个号码(0..6)。

现在的问题是,这不会的收益率在6号的。

会发生什么事是,当你击中的5索引的循环,你送的破发的要求。 中断()将导致循环不再过程中的任何值&GT; 5 ,但过程中的所有值&LT; 5

不过,这已经开始的任何值大于5仍将得到处理。由于各项指标并行运行时,它们就不再是有序的,所以你会得到不同的运行,其中一些值&GT; 5 (如8在你的例子)仍正在执行。

  

哪些迭代?整体迭代计数器?或每线程?我是pretty的肯定就是每个线程。请谅解。

这是被传递到的Parallel.For指数。中断()不会的 prevent 的从项目正在处理,但提供的所有项目多达100个得到处理的保证,但高于100项可能会或可能不会得到处理。

  

我说得对不对?就是这就是为什么我在我的例子获得超过5元的原因是什么?

是的。如果您使用的是分区就像你已经证明,只要您拨打中断(),超过一个,你打破将不再获得计划项目。然而,项目(这是的整个分区的)已计划将得到完全处理。在你的榜样,这意味着你可能总是处理所有1000项。

  

我如何才能真正突破的时候(我== 5)?

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

  

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

您应该使用<一个href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallelloopstate.stop.aspx"><$c$c>Stop()而不是中断()如果你想要的东西,以尽快停止。这不会prevent项目的已经从停止运行的,但将不再安排任何物品(包括以较低的指数那些或更早枚举比你的当前位置)。

I'm investigating the Parallelism Break in a For loop.

After reading this and this I still have a question:

I'd expect this code :

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

To yield at most 6 numbers (0..6). not only he is not doing it but have different result length :

02351486
013542
0135642

Very annoying. (where the hell is Break() {after 5} here ??)

So I looked at msdn

Break may be used to communicate to the loop that no other iterations after the current iteration need be run. If Break is called from the 100th iteration of a for loop iterating in parallel from 0 to 1000, all iterations less than 100 should still be run, but the iterations from 101 through to 1000 are not necessary.

Quesion #1 :

Which iterations ? the overall iteration counter ? or per thread ? I'm pretty sure it is per thread. please approve.

Question #2 :

Lets assume we are using Parallel + range partition (due to no cpu cost change between elements) so it divides the data among threads . So if we have 4 cores (and perfect divisions among them):

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

so the thread in core #1 will meet value=100 sometime and will break. this will be his iteration number 100 . But the thread in core #4 got more quanta and he is on 900 now. he is way beyond his 100'th iteration. He doesnt have index less 100 to be stopped !! - so he will show them all.

Am I right ? is that is the reason why I get more than 5 elements in my example ?

Question #3 :

How cn I truly break when (i == 5) ?

p.s.

I mean , come on ! when I do Break() , I want things the loop to stop. excactly as I do in regular For loop.

解决方案

To yield at most 6 numbers (0..6).

The problem is that this won't yield at most 6 numbers.

What happens is, when you hit a loop with an index of 5, you send the "break" request. Break() will cause the loop to no longer process any values >5, but process all values <5.

However, any values greater than 5 which were already started will still get processed. Since the various indices are running in parallel, they're no longer ordered, so you get various runs where some values >5 (such as 8 in your example) are still being executed.

Which iterations ? the overall iteration counter ? or per thread ? I'm pretty sure it is per thread. please approve.

This is the index being passed into Parallel.For. Break() won't prevent items from being processed, but provides a guarantee that all items up to 100 get processed, but items above 100 may or may not get processed.

Am I right ? is that is the reason why I get more than 5 elements in my example ?

Yes. If you use a partitioner like you've shown, as soon as you call Break(), items beyond the one where you break will no longer get scheduled. However, items (which is the entire partition) already scheduled will get processed fully. In your example, this means you're likely to always process all 1000 items.

How can I truly break when (i == 5) ?

You are - but when you run in Parallel, things change. What is the actual goal here? If you only want to process the first 6 items (0-5), you should restrict the items before you loop through them via a LINQ query or similar. You can then process the 6 items in Parallel.For or Parallel.ForEach without a Break() and without worry.

I mean , come on ! when I do Break() , I want things the loop to stop. excactly as I do in regular For loop.

You should use Stop() instead of Break() if you want things to stop as quickly as possible. This will not prevent items already running from stopping, but will no longer schedule any items (including ones at lower indices or earlier in the enumeration than your current position).

这篇关于的Parallel.For和休息()的误解?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆