https://msdn.microsoft.com/en-us/library/dd997416(v=vs.110).aspx声称可以为Parallel.ForEach
编写一个自定义分区程序,其中"一次提供[es multiple]元素"。如何做到这一点?
我有一个超过750,000个任务的集合,我尝试与Parallel.For
或Parallel.ForEach
并行执行。 (我目前正在使用For
,但自定义分区程序显然需要ForEach
。)总处理时间约为30个处理器分钟, 大约需要4分钟八核。
"宜"是一个有效的术语。工作量非常不同,只有前五个需要20分钟。如果它们在五个独立的线程上运行,那就没问题,但似乎默认的分区程序(非常明智地)假设任务都需要大约相同的时间,因此在同一个线程上运行前十几个。
由于我的工作负载不是这种情况,我想编写一个自定义分区程序,一次分配前32个任务,一次分配两个64个,接下来分别分配128个,以及等等。 https://msdn.microsoft.com/en-us/library/dd997416(v=vs.110).aspx声称提供了如何创建自定义分区程序的示例。有了精算,页面上写着:
每次分区在枚举器上调用
MoveNext
时,枚举器都会为分区提供一个列表元素。
[...]
这是块分区的示例,每个块由一个元素组成。
到目前为止,这么好。我合理地确定了代码所说的内容,我当然看到MoveNext
调用一次只能得到一个元素。
然后继续:
通过一次提供更多元素,您可以减少对锁定的争用,理论上可以实现更快的性能。
现在我很困惑。该文字让我想要用yield return
的内容替换yield return new List<KeyValuePair<long, TSource>>
。这显然不好,但我不知道如何获取我的目标分区程序。或者甚至如何获得一个相对简单的分区器,就像一个无条件地一次返回两个元素的分区器一样
鉴于我的工作量,我非常肯定我想开始&#34;一次提供更多元素&#34;一旦我完成了前几个重量级的任务,但我无法弄清楚我将如何做到这一点。如何更改该示例代码以提供具有多个元素的块?
注1:我意识到我的前32个任务&#34;很随意。一旦我得到了一个可以满足我想要的自定义分区程序,我完全打算调整它以查看改进了什么以及什么没有改进。
注2:我意识到我实际上并不需要这里的自定义分区程序。改组任务也可能解决默认分区程序的不良行为 但这对我来说是一个学习项目,我想学习如何编写自定义分区程序。豁免默认分区程序是一个不同的项目。