2

我在 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);

那么这可能是问题,某种内部数组复制吗?如果这是问题所在,应如何处理此数组声明以避免异常?

4

0 回答 0