並列処理を使用していくつかのネストされたループを高速化しようとしていますが、構文を正しく取得できません。私は、ビットマップ内のいくつのピクセルが赤、白、または黒であるかのカウントを取得しようとしています。これは、別の場所で列挙型の値です。Parallel for C#で共有変数を使用する
:私は、以下のように共有変数を更新マイクロソフト社とstackoverflowのからのループの並列のコードを見てきた Bitmap image = new Bitmap(@"Input.png");
var colourCount = new int[3];
for (var x = 0; x < image.Width; x++)
{
for (var y = 0; y < image.Height; y++)
{
switch (image.GetPixel(x, y).ToArgb())
{
case (int)colours.red: colourCount[0]++; break;
case (int)colours.white: colourCount[1]++; break;
case (int)colours.black: colourCount[2]++; break;
default: throw new ArgumentOutOfRangeException(string.Format("Unexpected colour found: '{0}'", image.GetPixel(x, y).ToArgb()));
}
}
}
:シリアル処理で
Iが正常に動作し、次のコードを有します
Parallel.For<int>(0, result.Count,() => 0, (i, loop, subtotal) =>
{
subtotal += result[i];
return subtotal;
},
(x) => Interlocked.Add(ref sum, x)
);
しかし、すべての例では、共有変数としてint型などの単純型を使用しています。サイズ3の配列に書き込む構文はわかりません。私はこのすべてに間違っているのだろうか?
ところで、私はGetPixelがBitmap.LockBitsのようなものに比べて非常に遅いことをパフォーマンスの面で知っています。私はちょうどパラレルループの原理を正しいものにしようとしています。
実際には 'localFinally'に' lock'は必要ありません。代わりに、あなたのループで 'Interlocked.Add()'を使うことができます。 'lock'を使うともっと明白に正しいものになります。 – svick
@svick: 'Interlocked.Add'の複数の呼び出しは、単一の' lock'より効率が悪いかもしれません。 (「colourCount」が数十の要素で構成されていれば間違いありませんが、3の確信はありません。)[Albahari](http://www.albahari.com/threading/part4.aspx):「すべての''のメソッドは完全なフェンスを生成します。 "反復キャッシュ無効化オーバーヘッドは、単一ロックのコストを超える可能性があります。 – Douglas
これを投稿していただきありがとうございます。 GetPixelがスレッドセーフではないことを示唆しているのは間違いありません。実際には画像のプロパティやメソッドにアクセスするのはノーではないようです。だから私はそれを理解する必要があります。ループ自体が正常に動作しています。再度、感謝します! –