我最近一直在使用 PLINQ 来执行一些数据处理。
基本上我有大约 4000 个时间序列(所以基本上是 Dictionary<DataTime,T>
的实例),我将它们存储在一个名为 timeSeries
的列表中.
要执行我的操作,我只需执行以下操作:
timeSeries.AsParallel().ForAll(x=>myOperation(x))
如果我查看我的不同内核发生了什么,我注意到首先,我所有的 CPU 都在使用,并且我在控制台(我输出一些日志的地方)上看到同时处理多个时间序列时间。
但是这个过程很漫长,大约45分钟后,日志记录清楚地表明只有一个线程在工作。这是为什么?
我试着给它一些思考,然后我意识到 timeSeries
包含更容易从 myOperation
处理的实例列表开头和结尾的观点。所以,我想知道 PLINQ 使用的算法是否可能包括将 4000 个实例拆分到 4 个内核上,每个内核分配 1000 个实例。然后,当内核完成其工作分配后,它会返回空闲状态。这意味着其中一个核心可能面临更重的工作量。
我的理论是正确的还是有其他可能的解释?
我应该在运行列表之前打乱列表,还是可以使用某种并行参数来解决该问题?
最佳答案
你的理论可能是正确的,尽管有一种叫做“工作窃取”的东西可以反驳这一点。我不确定为什么这在这里不起作用。外端有很多(>= 几十个)大型作业还是只有几个?
除了打乱数据之外,您还可以使用 the overload对于接受 custom Partioner 的 AsParallel()
.这将使您能够更好地平衡工作。
旁注:对于这种情况,我更喜欢 Parallel.ForEach()
,更多选项和更简洁的语法。
关于c# - 为什么我的 Parallel.ForAll 调用最终使用单个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17852021/