4

従来の構文を使用して記述したループがいくつかあります

foreach(x in xs) {....}

これらのループのいくつかは、計算に関してかなり集約的であり、私は次のような並列構文を使用してそれらを変更しました:

Parallel.ForEach(x, xs => {...});

大幅なパフォーマンスアップが見られます!! 私の質問は次のとおりです。並列マルチスレッドを使用してバグを導入していますか? スレッドセーフは複雑で、奇妙なバグを引き起こす可能性があると読みました。私は何を気にする必要がありますか?

4

2 に答える 2

4

共有状態にアクセスしても、ほとんどの場合、望ましい結果が得られません。簡単な例:

int sum = 0;
for (int i = 0; i < 1000000; i++)
{
    sum++;
}

これをに変更

Parallel.For(0, 1000000, i => { sum++; });

sum複数のスレッドが読み取り/書き込みを行っているため、ランダムな値が表示されますsum

更新をロックすると問題は解決しますが、基本的に操作を順次操作に戻すことになります。

ループ内で何が起こっても安全であることを確認する必要があります。

Microsoft Patterns and Practices はこれらすべてを説明する本を作成しました。並列ループを使用するようにコードを単純に変更する前に、それを確認する必要があります。

于 2012-07-23T16:57:09.090 に答える
2

確実に言うと、反復/ループコードを投稿してください。

ただし、一般的に、反復は互いに独立し、共有状態を回避する必要があります。並列反復リソースにまたがる共有リソースは、バグを引き起こす可能性があります。

また、計算が他の計算または並列操作またはループに依存している場合は、TPL タスク チェーンを使用する方が適切であり、クロススレッド リソースの共有を回避するのにも役立ちます。

より多くの情報とサンプル、パターン/アンチパターンについては、無料の Microsoft ブックで説明されています: 並列プログラミングのパターン: .NET Framework 4 による並列パターンの理解と適用

ダウンロードはこちら

http://www.microsoft.com/en-us/download/details.aspx?id=19222

于 2012-07-23T16:51:55.817 に答える