1

Parallel Extensions を使用する場合、MemoryBarriers について考慮する必要はありますか?

編集 - 元の質問が自由回答形式だったので詳しく説明します: (@xanatos の回答は私が探していたものでした)

具体的な例を挙げると、Parallel.ForEach を使用し、各反復がクラス内のプロパティの値を設定するとします (各反復は独自の特定のプロパティを設定し、2 つの反復で同じプロパティの値を設定することはありません)。Parallel.ForEach を呼び出した同じスレッドで、Parallel.ForEach から設定されたプロパティにアクセスします。

class Program
{
  static void Main(string[] args)
  {
    var t = new Test();
    t.InitializePropertiesInParallel();
    var a = t.PropA; // Could never be 0?
    var b = t.PropB; // Could never be 0?
  }
}

public class Test
{
  public int PropA { get; set; }
  public int PropB { get; set; }

  public void InitializePropertiesInParallel()
  {
    var initializers = new List<Action<int>>()
    {
      i => PropA = i,
      i => PropB = i
    };

    initializers.AsParallel().ForAll(a => a(1));
  }
}
4

2 に答える 2

2

ここで1つのことを覚えておいてください:キャッシュラインの無効化。これは複雑なトピックですが、ここにすばらしいMSDNの記事があります

この特定の例での要点は、2つの異なるスレッドから同じオブジェクトインスタンスを変更しているため、メモリ内のまったく同じ場所に触れていなくても、同じキャッシュラインに触れているということです。プロセッサ1の最初のスレッドがメモリを変更すると、プロセッサ2が再度読み取り/書き込みを行う前に、キャッシュがフラッシュおよび更新されます。

とはいえ、2つの小道具だけを使用した特定の例を考えると、これはマイクロ最適化であり、まったく心配する必要はありません。あなたがそれを外挿することになった場合に注意すべきことだけです。

于 2012-03-15T07:13:21.213 に答える
1

すべてのワーカーが他のワーカーによって準備されたデータを必要としない場合 (したがって、ワーカー 1 が A を書き込み、ワーカー 2 が A を読み取る状況はありません)、 は必要ありませんMemoryBarrier。すべてのタスクが終了すると、Waitとして機能する がありMemoryBarrierます (最終的には、見えなくても、すべてのワーカーが終了するのを待つ同期構造がどこかにあります)。

于 2012-03-13T17:29:45.407 に答える