如何以缓慢的产出并行化 IEnumerable(这使得 PLINQ 无用)?
How to parallelize an IEnumerable with a slow yield (which renders PLINQ useless)?
我在寻找一种正确并行处理 IEnumerable
的方法时遇到了一些麻烦,其中每个项目的实际生成都需要相当长的时间,因此每次调用都会有效地锁定一点reader 一侧的 MoveNext
。
这是我的场景:
I have a method that takes an IEnumerable<(float[], float[])>
(the specific type doesn't actually matter here), and I need to compute those items, split them into batches of a fixed side, then process every batch.
假设我已经准备好分区代码(参见 this answer here)以及处理每个单独分区的代码。
问题是,正如我所说,从初始列表中生成每个值都涉及一些 IO/CPU 操作(通常会读取图像,处理它并 return 这两个矩阵有),所以即使有:
var items = dataset.AsParallel().Partition(size).ToArray().AsParallel().Select(partition =>
{
// Process the partitions here..
return partition;
}).ToArray(); // Two AsParallel calls because I'm doing two selections one after the other
我使用了大约 25% CPU(我有一个 8 核 AMD FX-8350),因为我猜这是第一个列表中项目的实际生成导致枚举变慢,甚至在开始第一个 AsParallel
电话之前。
我在想一个可能的解决方案是要求此方法的用户提供一个 IEnumerable<Func<(float[], float[])>>
,因为这将使我的方法能够轻松地并行处理这些元素。
我的问题是:这是唯一可能的解决方案,还是有另一种方法可以并行枚举 "locking" IEnumerable
,而不会导致每个项目的产生不是并行的?
谢谢!
编辑:澄清一下,我不是在第一个 IEnumerable
中编写实际代码,这取决于相关图书馆的用户,它将输入自己的 IEnumerable
以便图书馆分成批次并继续工作。
我希望有替代 Func
委托的原因之一是,在用户方面,仅 returning 一个元组比必须显式 return 更容易和更直观 return 一个懒惰地计算整个事情的函数。
恐怕你不能。如果最初的 IEnumerable
很慢,那么无论您在并行化和处理能力方面使用多少资源,都无法作为第二步来使其更快。最好的情况是您添加的越少越好。但是还是很慢。
解决方案是看看是否可以通过任何方式加快原始的初始序列。
我在寻找一种正确并行处理 IEnumerable
的方法时遇到了一些麻烦,其中每个项目的实际生成都需要相当长的时间,因此每次调用都会有效地锁定一点reader 一侧的 MoveNext
。
这是我的场景:
I have a method that takes an
IEnumerable<(float[], float[])>
(the specific type doesn't actually matter here), and I need to compute those items, split them into batches of a fixed side, then process every batch.
假设我已经准备好分区代码(参见 this answer here)以及处理每个单独分区的代码。
问题是,正如我所说,从初始列表中生成每个值都涉及一些 IO/CPU 操作(通常会读取图像,处理它并 return 这两个矩阵有),所以即使有:
var items = dataset.AsParallel().Partition(size).ToArray().AsParallel().Select(partition =>
{
// Process the partitions here..
return partition;
}).ToArray(); // Two AsParallel calls because I'm doing two selections one after the other
我使用了大约 25% CPU(我有一个 8 核 AMD FX-8350),因为我猜这是第一个列表中项目的实际生成导致枚举变慢,甚至在开始第一个 AsParallel
电话之前。
我在想一个可能的解决方案是要求此方法的用户提供一个 IEnumerable<Func<(float[], float[])>>
,因为这将使我的方法能够轻松地并行处理这些元素。
我的问题是:这是唯一可能的解决方案,还是有另一种方法可以并行枚举 "locking" IEnumerable
,而不会导致每个项目的产生不是并行的?
谢谢!
编辑:澄清一下,我不是在第一个 IEnumerable
中编写实际代码,这取决于相关图书馆的用户,它将输入自己的 IEnumerable
以便图书馆分成批次并继续工作。
我希望有替代 Func
委托的原因之一是,在用户方面,仅 returning 一个元组比必须显式 return 更容易和更直观 return 一个懒惰地计算整个事情的函数。
恐怕你不能。如果最初的 IEnumerable
很慢,那么无论您在并行化和处理能力方面使用多少资源,都无法作为第二步来使其更快。最好的情况是您添加的越少越好。但是还是很慢。
解决方案是看看是否可以通过任何方式加快原始的初始序列。