c# - Multiple Parallel.ForEach calls, MemoryBarrier? -
i have bunch of data rows, , want use parallel.foreach compute value on each row this...
class datarow { public double { get; internal set; } public double b { get; internal set; } public double c { get; internal set; } public datarow() { = double.nan; b = double.nan; c = double.nan; } } class program { static void parallelforeachtoyexample() { var rnd = new random(); var df = new list<datarow>(); (int = 0; < 10000000; i++) { var dr = new datarow {a = rnd.nextdouble()}; df.add(dr); } // ever needed? (i) //thread.memorybarrier(); // parallel each (ii) parallel.foreach(df, dr => { dr.b = 2.0*dr.a; }); // ever needed? (iii) //thread.memorybarrier(); // parallel each 2 (iv) parallel.foreach(df, dr => { dr.c = 2.0 * dr.b; }); } }
(in example, there's no need parallelize , if there was, go inside 1 parallel.foreach. meant simplified version of code makes sense set this).
is possible reads re-ordered here end data row b != 2a or c != 2b?
say first parallel.foreach (ii) assigns worker thread 42 work on data row 0. , second parallel.foreach (iv) assigns worker thread 43 work on data row 0 (as first parallel.foreach finishes). there chance read of dr.b row 0 on thread 43 returns double.nan since hasn't seen write thread 42 yet?
and if so, inserting memory barrier @ iii @ all? force updates first parallel.foreach visible threads before second parallel.foreach starts?
the work started parallel.foreach()
done before returns. internally, foreach()
spawns task
each iteration, , calls wait()
on each one. result, not need synchronize access between foreach()
calls.
you do need keep in mind individual tasks foreach()
overloads allow access loop state, aggregating results tasks, etc. example in trivial example sums 1 ≤ x ≤ 100
, action
passed localfinally
of parallel.for()
has concerned 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 use of `interlocked` static method }); // work of previous `for()` call guaranteed done here console.writeline(total);
in example, not necessary insert memory barrier between foreach()
calls. specifically, loop iv
can depend on results of ii
being completed, , parallel.foreach()
inserted iii
you.
snippet sourced from: parallel framework , avoiding false sharing
Comments
Post a Comment