3

我知道为短期运行任务提供细粒度控制的任务,但我有一种情况,使用 foreach 循环更自然。问题是,是否有可能告诉 Parallel.For 期望短期运行的操作并使用尽可能多的线程来最大限度地利用 CPU?

如果不是,那么您建议使用什么方法进行并行化:

bool [,] grid = new bool [1000, 1000];
for (int y=0; y<1000; y++)
    for (int x=0; x<1000; x++)
        // Ignore the bounds error. This is just to illustrate a very short operation.
        grid[x, y] |= grid[x-1, y+1];
4

1 回答 1

6

问题是,是否有可能告诉 Parallel.For 期望短期运行的操作并使用尽可能多的线程来最大限度地利用 CPU?

是的,您可以通过自己制作Partitioner<T>和处理分区来做到这一点。有关详细信息,请参阅如何:加速小型循环体

但是,在您的情况下,最好只并行化外部循环,并将内部循环留在每个外部Parallel.For循环主体内部。这将为每个工作项提供足够的指令,使其可能充分使用处理器。

话虽如此,在这种情况下,.NET 可能不会做得很好Parallel.For——至少在没有一些额外工作的情况下不会。通过将值并行分配给同一个数组,由于隐式数组边界检查,您将引入错误共享,它从同一位置(就在数组开始之前)读取。

有多种方法可以解决这个问题 - 例如,一种选择可能是从多维数组切换到锯齿状数组。通过正确的索引和循环,这可以减少对“共享”数组的写入次数。另一种选择是使用不安全的代码和指针而不是直接数组访问,因为这避免了边界检查,但需要非常仔细的编码。

于 2012-09-20T15:44:06.593 回答