Multiple Parallel.ForEach calls, MemoryBarrier?
The work started by a Parallel.ForEach()
will be done before it returns. Internally, ForEach()
spawns a Task
for each iteration, and calls Wait()
on each one. As a result, you do not need to synchronize access between ForEach()
calls.
You do need to keep that in mind for individual tasks with ForEach()
overloads that allow you access to loop state, aggregating results from tasks, etc. For example in this trivial example which sums up 1 ≤ x ≤ 100
, the Action
passed to localFinally
of Parallel.For()
has to be concerned about synchronization issues,
var total = 0;Parallel.For(0, 101, () => 0, // <-- localInit(i, state, localTotal) => { // <-- body localTotal += i; return localTotal;}, localTotal => { <-- localFinally Interlocked.Add(ref total, localTotal); // Note the use of an `Interlocked` static method});// Work of previous `For()` call is guaranteed to be done hereConsole.WriteLine(total);
In your example, it is not necessary to insert a memory barrier between the ForEach()
calls. Specifically, loop IV
can depend on the results of II
being completed, and Parallel.ForEach()
already inserted III
for you.
Snippet sourced from: Parallel Framework and avoiding false sharing
Since more than one thread will be accessing the same variable "dr.B", you will need to make sure your C# code is thread-safe.
Try using "lock" round each operationhttps://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
e.g.
private Object thisLock1 = new Object();...lock(thisLock1){ dr.C = 2.0 * dr.B;}...lock(thisLock1){ dr.B = 2.0*dr.A;}
However, doing this will defeat the parallel processing. since each thread has to wait until the next one is done.
Make sure to read the potential pitfall with parallel processing:https://msdn.microsoft.com/en-us/library/dd997403%28v=vs.110%29.aspx