views:

51

answers:

4

I want to convert a for loop which increments the iterator by 2 every pass into a Parallel For loop using the TPL. The data is not order dependent or constrained in any way, but I only want to process the data in every other element of my source array (which is _Datalist in the code below), hence the need to increment by 2.

My For Loop:

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

Is it possible to tell the parallel loop that I want to increment i by two instead of one?

Here's the Parallel Loop, but obviously i is only incrementing by 1 each iteration:

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

I could tell the inner loop body to ignore odd values of i, but that seems a litle messy - is there a way of doing it in the loop initialisation somehow?

+3  A: 

You can halve the number of steps and double the indices:

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

or alternativley just create a new array that references to every other item and use the parrallel for on that?

John Nicholas
+4  A: 

How about:

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

Task.Factory.StartNew(() =>
    Parallel.ForEach(odds, i =>
    {
        // do work for _DataList[i]                    
    })
);
Darin Dimitrov
You've got good reputation for a reason
Hasan Khan
aha, I like your thinking. Thanks.
Gareth S
A: 

Darin Dimitrov's answer shows an easy way to accomplish this.

However, this wasn't added, as it's typically a sign that the loop bodies aren't truly distinct. In most cases, the need to use a different increment value typically only comes with the need for processing in a specific order or other concerns that will cause parallelization to create race conditions.

Reed Copsey
Noted for future reference, but in the case to which I'm applying this loop the processing order of the elements is really not a concern
Gareth S
@Gareth: I just mention this since there was actually a discussion (which I can't find atm) by Stephen Toub mentioning specifically why Parallel.For didn't add this feature - and it basically came down to it typically is problematic for parallel processing, but you can always work around it via a partitioner or parallel.foreach.
Reed Copsey