次のような C# のループがあります。
for (int level = 0; level < numLevels; level++){
for (int y = 0; y < ysize; y++){
for (int x = 0; x < xsize; x++){
outArray[y*xsize + x] = SomeMathWasDone(level);
}
}
}
Parallel.For ループを使用してこのコードを並列化したいのですが、少なくとも私が尋ねた以前の質問に対する Reed の回答によれば、これは非常に簡単に思えます。だから私は先に進み、これを行います:
for (int level = 0; level < numLevels; level++){
Parallel.ForEach(Partitioner.Create(0, ysize),
(range) => {
for (int y = range.Item1; y < range.Item2; y++){
for (int x = 0; x < xsize; x++){
outArray[y*xsize + x] = SomeMathWasDone(level);
}
}
});
}
このコードは System.AggregateException をスローします。内部例外は次のとおりです。
InnerException {"Destination array was not long enough. Check destIndex and length, and the array's lower bounds."} System.Exception {System.ArgumentException}
配列が適切なサイズであることはわかっています。コードが並列でない場合でも問題なく動作するからです。これは何を意味するのでしょうか?この問題をデバッグするにはどうすればよいですか? それとも、この性質のコードを並列化するときに、まったく別のことをする必要がありますか?
内部例外スタック トレースは次のとおりです。
at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length)
at System.Array.CopyTo(Array array, Int32 index)
at MyFunction(Single[] inImage, Int32 inXSize, Int32 inYSize, Int32 inLevels) ... line 100
その行に行った後、私はそれをいじって、それが問題であるかどうかを確認しました。行は次のとおりです。
float[] theKernel =
{1.0f, 4.0f, 6.0f, 4.0f, 1.0f,
4.0f, 16.0f, 24.0f, 16.0f, 4.0f,
6.0f, 24.0f, 36.0f, 24.0f, 6.0f,
4.0f, 16.0f, 24.0f, 16.0f, 4.0f,
1.0f, 4.0f, 6.0f, 4.0f, 1.0f};
そして、それはうまくいかないかもしれないと考えて、より明示的な方法を試しました:
//outside the function, now a member of the class
float[] downsizeKernel=
{1.0f, 4.0f, 6.0f, 4.0f, 1.0f,
4.0f, 16.0f, 24.0f, 16.0f, 4.0f,
6.0f, 24.0f, 36.0f, 24.0f, 6.0f,
4.0f, 16.0f, 24.0f, 16.0f, 4.0f,
1.0f, 4.0f, 6.0f, 4.0f, 1.0f};
//now inside the function
float[] theKernel = new float[25];
downsizeKernel.CopyTo(theKernel, 0);
それで、ある種の内部配列のコピーが問題になる可能性がありますか? それが問題である場合、例外を回避するためにこの配列宣言をどのように処理する必要がありますか?