Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel.For(): Update variable outside of loop

I'm just looking in to the new .NET 4.0 features. With that, I'm attempting a simple calculation using Parallel.For and a normal for(x;x;x) loop.

However, I'm getting different results about 50% of the time.

long sum = 0;  Parallel.For(1, 10000, y =>     {         sum += y;     } );  Console.WriteLine(sum.ToString());  sum = 0;  for (int y = 1; y < 10000; y++) {    sum += y; } Console.WriteLine(sum.ToString()); 

My guess is that the threads are trying to update "sum" at the same time.
Is there an obvious way around it?

like image 454
Inisheer Avatar asked May 05 '10 14:05

Inisheer


1 Answers

You can't do this. sum is being shared across you parallel threads. You need to make sure that the sum variable is only being accessed by one thread at a time:

// DON'T DO THIS! Parallel.For(0, data.Count, i => {     Interlocked.Add(ref sum, data[i]); }); 

BUT... This is an anti-pattern because you've effectively serialised the loop because each thread will lock on the Interlocked.Add.

What you need to do is add sub totals and merge them at the end like this:

Parallel.For<int>(0, result.Count, () => 0, (i, loop, subtotal) =>     {         subtotal += result[i];         return subtotal;     },     (x) => Interlocked.Add(ref sum, x) ); 

You can find further discussion of this on MSDN: http://msdn.microsoft.com/en-us/library/dd460703.aspx

PLUG: You can find more on this in Chapter 2 on A Guide to Parallel Programming

The following is also definitely worth a read...

Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4 - Stephen Toub

like image 100
Ade Miller Avatar answered Oct 11 '22 05:10

Ade Miller