问题 为什么我的.Net应用程序只使用单个NUMA节点?


我有一个带有2个NUMA节点的服务器,每个节点有16个CPU。我可以看到任务管理器中的所有32个CPU,前2行中的前16个(NUMA节点1)和后2行中的后16个(NUMA节点2)。

在我的应用程序中,我开始使用64个线程 Thread.Start()。当我运行应用程序时,它是CPU密集型的,只有前16个CPU处于忙碌状态,其他16个CPU处于空闲状态。

为什么?我在用 Interlocked.Increment() 很多。这可能是个原因吗? 有没有办法在特定的NUMA节点上启动线程?


2692
2017-11-09 16:13


起源



答案:


此外 gcserver 我们应该启用 GCCpuGroup 和 Thread_UseAllCpuGroups 所以配置应该更像:

<configuration
   <runtime>
      <gcServer enabled="true"/>
      <GCCpuGroup  enabled="true"/>
      <Thread_UseAllCpuGroups  enabled="true"/>
   </runtime>
</configuration>

GcCpuGroup 为多个CPU组启用垃圾收集 Thread_UseAllCpuGroups 支持跨运行时的所有CPU组管理线程分发。


9
2018-03-14 07:40





首先要检查的确是 app.config 确保设置必要的选项:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <runtime>
        <gcServer enabled="true" />
        <Thread_UseAllCpuGroups enabled="true" />
        <GCCpuGroup enabled="true" />
    </runtime>
    <startup> 
        <!-- 4.5 and later should work, use the one targeted -->
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>       
    </startup>
</configuration>

如果 app.config-Wizadry没有帮助,很可能你的机器不应该使用多个内核组(Kgroups)。然后,您可以检查您的BIOS NUMA Group Size Optimization 如果你有Gen9 HP。如果它在 Clustered 模式,目前的CLR(2017,.net 4.6.2)仅使用第一个。如果该计算机中的核心数不超过64个,则应该可以选择 Flat 将所有核心放在同一组中的布局。如果找不到, 您可能需要BIOS更新

有关详细信息,请参阅 无法在C#应用程序中为我的线程使用多个处理器组 这里是StackOverflow。它甚至有自己的 诊断工具


2
2018-05-05 14:24





您是否将垃圾收集器设置为服务器版本?

在app.config中,尝试:

<configuration
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

由于堆的分配方式,服务器GC在具有许多内核的机器中的许多线程上搅拌大量对象/数据时会产生巨大的差异。


1
2018-01-20 01:47



此设置不会更改行为。 - Viktor Jevdokimov


答案:


此外 gcserver 我们应该启用 GCCpuGroup 和 Thread_UseAllCpuGroups 所以配置应该更像:

<configuration
   <runtime>
      <gcServer enabled="true"/>
      <GCCpuGroup  enabled="true"/>
      <Thread_UseAllCpuGroups  enabled="true"/>
   </runtime>
</configuration>

GcCpuGroup 为多个CPU组启用垃圾收集 Thread_UseAllCpuGroups 支持跨运行时的所有CPU组管理线程分发。


9
2018-03-14 07:40





首先要检查的确是 app.config 确保设置必要的选项:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <runtime>
        <gcServer enabled="true" />
        <Thread_UseAllCpuGroups enabled="true" />
        <GCCpuGroup enabled="true" />
    </runtime>
    <startup> 
        <!-- 4.5 and later should work, use the one targeted -->
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>       
    </startup>
</configuration>

如果 app.config-Wizadry没有帮助,很可能你的机器不应该使用多个内核组(Kgroups)。然后,您可以检查您的BIOS NUMA Group Size Optimization 如果你有Gen9 HP。如果它在 Clustered 模式,目前的CLR(2017,.net 4.6.2)仅使用第一个。如果该计算机中的核心数不超过64个,则应该可以选择 Flat 将所有核心放在同一组中的布局。如果找不到, 您可能需要BIOS更新

有关详细信息,请参阅 无法在C#应用程序中为我的线程使用多个处理器组 这里是StackOverflow。它甚至有自己的 诊断工具


2
2018-05-05 14:24





您是否将垃圾收集器设置为服务器版本?

在app.config中,尝试:

<configuration
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

由于堆的分配方式,服务器GC在具有许多内核的机器中的许多线程上搅拌大量对象/数据时会产生巨大的差异。


1
2018-01-20 01:47



此设置不会更改行为。 - Viktor Jevdokimov