Parallel.For可以针对非常短的运行操作进行优化吗



我知道一些任务可以为短时间运行的任务提供细粒度控制,但在这种情况下,使用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];

问题是,是否可以告诉Parallel。对于期望短时间运行的操作并使用尽可能多的线程来最大限度地提高CPU?

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

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

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

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

最新更新