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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With