我在 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);
那么这可能是问题,某种内部数组复制吗?如果这是问题所在,应如何处理此数组声明以避免异常?