我在找到一种正确并行化IEnumerable
处理的方法时遇到了一些麻烦,其中每个项目的实际生成需要相当长的时间,所以它有效地锁定了每次调用{ {1}}在读者方面。
这是我的情景:
我有一个方法需要
MoveNext
(特定类型在这里并不重要),我需要计算这些项目,将它们分成固定侧的批次,然后处理每个批次。< / p>
假设我已准备好分区代码(请参阅this answer here)以及处理每个分区的代码。
问题在于,正如我所说,从初始列表中产生每个值都涉及一些IO / CPU操作(一个通常会读取一个图像,处理它并返回这两个矩阵),所以即使:< / p>
IEnumerable<(float[], float[])>
我获得了大约25%的CPU使用率(我有一个8核AMD FX-8350),因为我猜它是第一个列表中实际生成的项目导致枚举速度很慢,甚至在进入第一次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
来电。
我在想一个可能的解决方案是要求此方法的用户改为提供AsParallel
,因为这样我的方法可以轻松地并行处理这些元素。
我的问题是:这是唯一可行的解决方案,还是有另一种方法可以并行枚举“锁定”IEnumerable<Func<(float[], float[])>>
,而不会导致每个项目不是并行导致这种减速?
谢谢!
修改:澄清,我没有在第一个IEnumerable
中编写实际代码,这取决于相关库的用户,将为库输入自己的IEnumerable
以分成批次并继续工作。
我希望有IEnumerable
委托的替代方案的原因之一是因为,在用户方面,只返回一个元组比显式返回一个懒惰计算的函数更容易,更直观整件事。
答案 0 :(得分:0)
我怕你不能。如果初始IEnumerable
很慢,那么无论您使用多少资源并行化和处理能力,都无法做第二步,以使其更快。最佳情况是您尽可能少地添加。但它仍然很慢。
解决方案是看看原始的初始序列是否可以通过任何方式加速。