ich eine Reihe von Datenzeilen haben, und ich möchte Parallel.ForEach verwenden, wie dies einige Wert in jeder Zeile zu berechnen ...Mehrere parallele. Für jeden Anruf, MemoryBarrier?
class DataRow
{
public double A { get; internal set; }
public double B { get; internal set; }
public double C { get; internal set; }
public DataRow()
{
A = double.NaN;
B = double.NaN;
C = double.NaN;
}
}
class Program
{
static void ParallelForEachToyExample()
{
var rnd = new Random();
var df = new List<DataRow>();
for (int i = 0; i < 10000000; i++)
{
var dr = new DataRow {A = rnd.NextDouble()};
df.Add(dr);
}
// Ever Needed? (I)
//Thread.MemoryBarrier();
// Parallel For Each (II)
Parallel.ForEach(df, dr =>
{
dr.B = 2.0*dr.A;
});
// Ever Needed? (III)
//Thread.MemoryBarrier();
// Parallel For Each 2 (IV)
Parallel.ForEach(df, dr =>
{
dr.C = 2.0 * dr.B;
});
}
}
(In diesem Beispiel gibt es keine Notwendigkeit zu parallelisieren und wenn es war, es könnte alles in eine Parallel.ForEach gehen, aber das soll eine vereinfachte Version von Code sein, wo es Sinn macht, es so einzurichten.
Ist es möglich, dass die Lesevorgänge hier neu geordnet werden, sodass ich eine Datenzeile mit B! = 2A oder C! = 2B?
Sagen Sie die erste Parallel.ForEach (II) weist Worker-Thread 42 an Datenzeile 0 arbeiten. Und die zweite Parallel.ForEach (IV) weist Worker-Thread 43 zu Datenzeile 0 arbeiten (sobald die erste Parallele .Für jedes Ende). Gibt es eine Chance, dass das Lesen von dr.B für Zeile 0 auf Thread 43 double.NaN zurückgibt, da es das Schreiben von Thread 42 noch nicht gesehen hat?
Und wenn ja, hilft das Einfügen einer Speicherbarriere bei III überhaupt? Würde dies die Updates von der ersten Parallel.ForEach für alle Threads erzwingen, bevor die zweite Parallel.ForEach startet?
Kurz gesagt .. Ich glaube nicht, dass Sie die explizite Gedächtnis Barrieren müssen .. eine Vermutung, dass die Umsetzung Parallel wäre.ForEach hat eine Art Synchronisation zum Beenden der Schleife/vor Aufruf 'ForEach' zurück –
ein besseres Bild von Ihrem aktuellen Code gegeben, könnte ich in der Lage sein, Ihnen eine bessere andere Antwort zu geben, als„Nein, darüber keine Sorge. " :) – jdphenix
Vielleicht ist der Grund für die Trennung ist ein wenig klarer, wenn ich sage, daß die Berechnung in jeder Zeile der zweiten parallelen Schleife (IV) auf einem Wert ab, die erst nach der ersten Schleife bekannt sein können (II) abgeschlossen ist. Nehmen wir an, wir brauchen den Mittelwert der Werte von dr.B über alle Zeilen hinweg, bevor wir den Wert von dr.C für jede Zeile berechnen können. –