如何将IEnumerable与缓慢的产量并行化(这使得PLINQ无用)?

时间:2017-12-05 19:48:04

标签: c# linq parallel-processing plinq

我在找到一种正确并行化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委托的替代方案的原因之一是因为,在用户方面,只返回一个元组比显式返回一个懒惰计算的函数更容易,更直观整件事。

1 个答案:

答案 0 :(得分:0)

我怕你不能。如果初始IEnumerable很慢,那么无论您使用多少资源并行化和处理能力,都无法做第二步,以使其更快。最佳情况是您尽可能少地添加。但它仍然很慢。

解决方案是看看原始的初始序列是否可以通过任何方式加速。