3

我正在将一些代码从 .NET 2 转移到 4 并使用 TPL 等。

虽然我确信这个问题一定是在 SO 上的某个地方问过的,但我找不到它。

我知道过度嵌套 TPL 任务可能会损害性能。

for (int y=0; y < h; y++)
    for (int x=0; x < w; x++)
        grid [x, y] = ((x + 1) * (y + 1));

您会将上面的外部或内部循环替换为 TPL,为什么?如果有一个额外的嵌套级别怎么办?

这是替换了内部循环的代码,在我的情况下它的表现更好了 1 秒。

int w = 10000;
int h = 10000;
int [,] grid = new int [w, h];
int [] index = new int [w * h];
DateTime time = DateTime.Now;
ParallelOptions options = new ParallelOptions();

options.MaxDegreeOfParallelism = Environment.ProcessorCount;

time = DateTime.Now;
for (int y=0; y < h; y++)
{
    Parallel.For
    (
        0,
        w,
        options,
        x =>
        {
            grid [x, y] = ((x + 1) * (y + 1));
        }
    );
}
span = DateTime.Now.Subtract(time);
Console.WriteLine("Filled in " + span.TotalSeconds.ToString() + " seconds.");

time = DateTime.Now;
for (int y=0; y < h; y++)
{
    Parallel.For
    (
        0,
        w,
        options,
        (x, state) =>
        {
            if (grid [x, y] < index.Length)
            {
                index [grid [x, y]]++;
            }
            else
            {
                state.Break();
            }
        }
    );
}
span = DateTime.Now.Subtract(time);
Console.WriteLine("Indexed in " + span.TotalSeconds.ToString() + " seconds.");
4

3 回答 3

4

在并行化内部循环时,您会看到更好的性能,因为在内存中是rect[x,]相邻的,而与 不相邻,因此并行化外循环将导致对相同内存空间的更多争用并减慢速度。rect[x+1,]rect[,y]rect[,y+1]

除了并行化外循环应该更快,所以如果你切换内循环和外循环,然后在外循环Parallel.For上做一个,你应该得到比当前测试更好的性能。

另一件值得注意的事情是边界检查有点昂贵,因此您还可以通过使用不安全的代码/指针而不是循环遍历大型数组来看到一些性能提升。

于 2012-07-29T21:02:53.203 回答
0

外部循环,因为使用内部循环会导致比外部循环更多的跨线程通信。

于 2012-07-29T18:56:32.253 回答
-1

两者都不!你甚至有性能问题吗?如果您提供的代码示例是真实的,那么看起来您可以从锯齿状数组中受益,其性能要好得多。

于 2012-07-29T19:02:26.977 回答