可以Parallel.For针对非常短时间运行进行优化吗?

时间:2012-09-20 15:37:54

标签: c# .net parallel-processing task-parallel-library

我知道为短期运行任务提供细粒度控制的任务,但我有一种情况是使用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];

1 个答案:

答案 0 :(得分:6)

  

问题是,是否有可能告诉Parallel.For期望短时间运行并使用尽可能多的线程来最大化CPU?

是的,您可以通过制作Partitioner<T>并自行处理分区来实现此目的。有关详细信息,请参阅How to: Speed Up Small Loop Bodies

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

话虽这么说,这种情况下.NET可能无法在Parallel.For上做得很好 - 至少在没有一些额外工作的情况下也是如此。通过并行地为相同数组赋值,您将引入false sharing,因为隐式数组边界检查,它从同一位置读取(就在开始之前)数组)。

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