我最近注意到LINQ的AsParallel
仅使用了我们即将成为生产系统的一半核心。所以我在LINQPad中写了一个小基准:
// should terminate with an AggregatException containing t overflows
// where t is the number of threads used
Enumerable.Range(0,Int32.MaxValue).AsParallel().Select(i=>
Enumerable.Range(0,i).Select(j=>(long)j).Sum()
+Enumerable.Range(0,Int32.MaxValue-i).Select(k=>(long)k).Sum()
).Sum()
在2插槽(16C / 32T)系统上运行这段代码只显示16个繁忙的核心(并完成16个溢出),这引出了我的初步问题: PLINQ是否限制为1套接字/ NUMA节点?或者这里的限制因素是什么?
更新
Environment.ProcessorCount.Dump("detected processor count");
是16而不是32,这可能是PLINQ首先只使用16个工作线程的原因。但话说回来,当明确使用.WithDegreeOfParallelism(32)
时,也只使用了16个核心。
It looks like we're also affected by the HP ProLiant Gen9 / Xeon E5 2600v3 Kgroup Clustred vs Flat configuration.。如果您有64个或更少的核心,请使用flat
,然后您可以再次使用所有核心。但是,如果你有更多核心,那么目前似乎没有解决方案。
PLINQ是否仅限于NUMA节点的问题仍然存在。我的猜测是:它并不关心NUMA节点,它只使用第一个内核组。