3

短期間のタスクをきめ細かく制御できるタスクを知っていますが、foreachループを使用する方が自然な状況です。問題は、Parallel.Forに短期間の操作を期待し、CPUを最大限に活用するためにできるだけ多くのスレッドを使用するように指示することは可能ですか?

そうでない場合、並列化するためにどのような方法を提案しますか?

bool [,] grid = new bool [1000, 1000];
for (int y=0; y<1000; y++)
    for (int x=0; x<1000; x++)
        // Ignore the bounds error. This is just to illustrate a very short operation.
        grid[x, y] |= grid[x-1, y+1];
4

1 に答える 1

6

問題は、Parallel.Forに短期間の操作を期待し、CPUを最大限に活用するためにできるだけ多くのスレッドを使用するように指示することは可能ですか?

はい、これを行うには、を作成しPartitioner<T>てパーティションを自分で処理します。詳細については、「方法:小さなループ本体を高速化する」を参照してください。

Parallel.Forただし、あなたの場合は、外側のループを並列化して、内側のループを各外側のループ本体の内側にシーケンシャルのままにしておく方がよい場合があります。これにより、各作業項目に十分な命令が与えられ、おそらくプロセッサを適切に使用できるようになります。

そうは言っても、これは.NETがうまく機能しない可能性が高い状況ですParallel.For-少なくともいくつかの追加の作業がなければ。同じ配列に並列に値を割り当てることにより、同じ場所(配列の開始直前)から読み取る暗黙的な配列境界チェックのために偽共有が導入されます。

これを回避するにはさまざまなアプローチがあります。たとえば、多次元配列からジャグ配列に切り替えることもできます。適切なインデックス作成とループを使用すると、「共有」アレイへの書き込み回数を減らすことができます。もう1つのオプションは、直接配列アクセスの代わりに安全でないコードとポインターを使用することです。これにより、境界チェックが回避されますが、非常に注意深いコーディングが必要になります。

于 2012-09-20T15:44:06.593 に答える