更改C#Parallel.For循环的增量值

问题描述:

我想转换一个for循环,它将迭代器每次递增2,并使用TPL将其递增为Parallel For循环。这些数据并不依赖于顺序或以任何方式受到约束,但我只想处理源数组中每个其他元素(在下面的代码中是_Datalist)中的数据,因此需要以2递增。更改C#Parallel.For循环的增量值

我For循环:

for (int i = 1; i < _DataList.Length - 1; i += 2) 
{ 
    // Do work for _DataList[i] 
} 

是否可以告诉并行循环,我想用两个而不是一个递增我?

这里的并行循环,但显然我只递增1每次迭代:

 Task.Factory.StartNew(() => 
      Parallel.For(1, _DataList.Length, i => 
      { 
       // do work for _DataList[i]      
      }) 
     ); 

我可以告诉内环体无视我的奇数值,但似乎痘痘杂乱 - 有以某种方式在循环初始化中实现它的一种方式?

+2

不要忽略奇数值;创建的任务数量是您需要的两倍,这会增加大量不必要的开销。 – Gabe 2010-10-20 16:59:48

+0

是的,我明白你的意思了 – Gareth 2010-10-20 17:41:02

如何:

var odds = Enumerable.Range(1, _DataList.Length).Where(i => i % 2 != 0); 

Task.Factory.StartNew(() => 
    Parallel.ForEach(odds, i => 
    { 
     // do work for _DataList[i]      
    }) 
); 
+0

你有良好的声誉 – 2010-10-20 17:11:27

+0

啊哈,我喜欢你的想法。谢谢。 – Gareth 2010-10-20 17:33:09

可以减少一半的步数,并增加一倍的指标:

Parallel.For(0, _DataList.Length/2, i => 
{ 
    // do work for _DataList[2 * i]      
}); 

Darin Dimitrov's answer显示了一个简单的方法来做到这一点。

但是,这并没有被添加,因为它通常表示循环体不是真正独特的。在大多数情况下,需要使用不同的增量值,通常只需要按照特定的顺序进行处理或其他问题,这会导致并行化以创建竞争条件。

+0

注意以备将来参考,但在应用此循环的情况下,元素的处理顺序实际上不是问题 – Gareth 2010-10-20 17:40:07

+0

@Gareth:我刚才提到了这个,因为实际上有一个讨论(我找不到atm)Stephen Toub特别提到了为什么Parallel.For没有添加这个特性 - 它基本上归结为它对于并行处理来说通常是有问题的,但是你总是可以通过分区器或者parallel.foreach来解决它。 – 2010-10-20 17:44:10

+0

我相信这个用例在使用.NET中的SIMD指令时很自然地出现,因为它们通过为数组的每个第n个元素创建一个'Vector '来操作,其中N是矢量的宽度。您无法利用Parallel.For来实现小型向量化函数,因为枚举器或乘法技巧会损害perf性能。 – jackmott 2016-07-26 17:06:56

只跳过偶数值。

Task.Factory.StartNew(() => 
       Parallel.For(1, _DataList.Length, i => 
       { 
        if(i % 2 == 0) 
        { 
         // do work for 
        } 
       }) 
      ); 
+1

你能解释更多关于你的答案吗?对于你给出的答案给出一些信息或解释通常被认为是很好的做法。这可能有助于未来的用户或OP更多。 – Bono 2015-09-19 09:25:42

+0

我是“juniour”,我不知道我在做什么! :) – Junior 2015-09-19 11:54:34

+0

这不是一个好主意,因为您正在创造开销,并且正是我想避免的 - 请参阅问题的第一条评论。幸运的是5年前有一些很好的解决方案:) – Gareth 2015-09-21 08:07:56