我有一大堆的数据行的,我想用Parallel.ForEach计算在这样的每一行一定的价值...多个Parallel.ForEach调用,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;
});
}
}
(在这个例子中,没有必要进行并行化,如果有是的,它可以全部放在一个Parallel.ForEach里面,但是这意味着它是一些代码的简化版本,它可以像这样设置它)。
是否有可能在这里重新排序读取,以便最终得到一个数据行,其中B!= 2A或C!= 2B?
说出第一个Parallel.ForEach(II)指派工作线程42工作在数据行0上。第二个Parallel.ForEach(IV)指派工作线程43工作在数据行0上(只要第一个并行.ForEach完成)。是否有机会读取dr.B在线程43上的第0行返回double.NaN,因为它没有看到来自线程42的写入呢?
如果是这样,插入一个内存障碍在III帮助吗?这是否会迫使第一个Parallel.ForEach的更新在第二个Parallel.ForEach启动之前对所有线程都可见?
总之..我不认为你需要的外显记忆障碍..一个猜测将是并行的,落实。ForEach在结束循环时有某种同步/在调用ForEach之前返回 –
如果您对实际代码有更好的了解,我可能会给您一个更好的答案,而不是“不要担心它。 “ :) – jdphenix
也许如果我说第二个并行循环(IV)的每一行中的计算取决于某些只能在第一个循环(II)完成后才知道的值,那么分离的原因会更清楚一些。假设我们需要所有行的dr.B值的中位数,然后才能计算每行dr.C的值。 –