Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为Parallel.ForEach创建自定义分区器 问题:_C#_Task Parallel Library_Parallel.foreach - Fatal编程技术网

C# 为Parallel.ForEach创建自定义分区器 问题:

C# 为Parallel.ForEach创建自定义分区器 问题:,c#,task-parallel-library,parallel.foreach,C#,Task Parallel Library,Parallel.foreach,声称可以为“一次提供多个”元素的Parallel.ForEach编写自定义分区程序。如何做到这一点 正当理由 我收集了超过750000个任务,试图与parallel.For或parallel.ForEach并行执行。(我目前正在使用For,但定制分区器显然需要ForEach)总处理时间约为30个处理器分钟,在8个内核上大约需要4分钟 “应该”是执行术语。工作负载非常不同,仅前五项就需要20分钟。如果它们在五个独立的线程上运行,这就可以了,但是默认的分区器(相当明智地)似乎假定所有任务都需要大约相

声称可以为“一次提供多个”元素的
Parallel.ForEach
编写自定义分区程序。如何做到这一点

正当理由 我收集了超过750000个任务,试图与
parallel.For
parallel.ForEach
并行执行。(我目前正在使用
For
,但定制分区器显然需要
ForEach
)总处理时间约为30个处理器分钟,在8个内核上大约需要4分钟

“应该”是执行术语。工作负载非常不同,仅前五项就需要20分钟。如果它们在五个独立的线程上运行,这就可以了,但是默认的分区器(相当明智地)似乎假定所有任务都需要大约相同的时间,因此在同一个线程上运行前十几个左右的任务

因为我的工作负载不是这样,所以我想编写一个自定义分区器,它一次分配前32个任务,下64个任务一次分配两个,下128个任务一次分配四个,依此类推。声明提供了如何创建自定义分区器的示例。页面上省略了以下内容:

每次分区在枚举器上调用
MoveNext
,枚举器都会为分区提供一个列表元素。
[…]
这是一个区块划分的示例,每个区块由一个元素组成

到目前为止,一切顺利。我很确定代码是这么说的,我也很清楚
MoveNext
调用一次只能得到一个元素

但它接着说:

通过一次提供更多的元素,您可以减少对锁的争用,并在理论上实现更快的性能

现在我很困惑。这段文字让我想用一个新列表开始的东西来替换
yield return
。这显然是不好的,但我不知道如何得到我的目标分区。甚至如何获得一个相对简单的分区器,比如一次无条件返回两个元素的分区器。
考虑到我的工作量,我非常确定,一旦我完成了最初几项繁重的任务,我会开始“一次提供更多的元素”,但我不知道如何才能做到这一点。如何更改示例代码以提供包含多个元素的块

尾注 注1:我意识到我的“前32项任务”相当随意。一旦我得到了一个定制的分区器,它可以满足我的需要,我就完全打算对它进行调整,看看有什么改进了,有什么不改进

注2:我意识到我实际上不需要自定义分区器。洗牌任务也可能解决默认分区器的不良行为。

但这对我来说是一个学习项目,我想学习如何编写自定义分区器。向默认分区器叩头是一个不同的项目。

尝试使用
分区器.Create(yourCollection,EnumerablePartitionerOptions.NoBuffering)执行此操作。
,这使得分区程序一次只能执行1。与分区无关:你在循环中做什么?你读/写文件/数据库吗?30分钟听起来太长了…尝试使用
partitioner.Create(yourCollection,enumerablepartitionoptions.NoBuffering)
,,这使得分区程序一次只能执行1。与分区无关:你在循环中做什么?你读/写文件/数据库吗?30分钟听起来太长了…尝试使用
partitioner.Create(yourCollection,enumerablepartitionoptions.NoBuffering)
,,这使得一个分区程序总是一次执行1。与分区无关:你在循环中做什么?你读/写文件/数据库吗?30分钟听起来太长了。。。