У меня есть куча строк данных, и я хочу использовать Parallel.ForEach для вычисления некоторого значения в каждой строке, как это...
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;
});
}
}
(В этом примере нет необходимости в распараллеливании, и если бы он был, все это могло бы войти в один Parallel.ForEach. Но это должна быть упрощенная версия некоторого кода, где имеет смысл настроить его таким образом).
Можно ли здесь переупорядочить чтения, чтобы в итоге я получил строку данных, где B != 2A или C != 2B?
Скажем, первый Parallel.ForEach (II) назначает рабочий поток 42 для работы со строкой данных 0. А второй Parallel.ForEach (IV) назначает рабочий поток 43 для работы со строкой данных 0 (как только первый Parallel.ForEach завершится) . Есть ли шанс, что чтение dr.B для строки 0 в потоке 43 вернет double.NaN, поскольку он еще не видел записи из потока 42?
И если да, то вставка барьера памяти на III вообще помогает? Заставит ли это обновления из первого Parallel.ForEach быть видимыми для всех потоков до запуска второго Parallel.ForEach?
ForEach
- person Vikas Gupta   schedule 15.05.2015