Skip to content

How do I configure my multithreaded .NET 6 application to use all Windows CPU groups? #12805

@Cherosev

Description

@Cherosev

I allready postet this question at (microsoft docs)[https://docs.microsoft.com/en-us/answers/questions/760023/how-do-i-configure-my-multithreaded-net-6-applicat.html], but they redirected me here.

I'm trying to migrate a project from .NET Framework 4.7.2 to .NET 6, but the performance of my program has dropped significantly. Parts of the program exploit parallelism for bulk operations on a server with 96 Cores and 192 Logical processors split across 4 CPU groups.

I'm running the program on a Windows Server 2016 with the .NET 6 Runtime installed (.NET 6 SDK not installed). The project is written in F# 6.0.

In .NET Framework 4.7.2 we used the following app.config-file which successfully made the program run across all 192 Logical processors, achieving ~98% CPU utilization:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <runtime>
 <Thread_UseAllCpuGroups enabled="true" />
 <GCCpuGroup enabled="true" />
 <gcServer enabled="true" />
 <gcAllowVeryLargeObjects enabled="true" />
 </runtime>
</configuration>

After migrating to .NET 6 (and by extension .NET Core) the CPU utilization dropped, and I am having trouble increasing it again.

According to Microsoft's own documentation app.config is not used to configure .NET Core projects, replaced by [appname].runtimeconfig.json. To accommodate this change i have added a runtimeconfig.template.json to my project:

{
  "configProperties": {
    "System.GC.CpuGroup": true,
    "System.GC.Server": true,
    "COMPlus_gcAllowVeryLargeObjects": 1
  }
}

This produces the following [appname].runtimeconfig.json-file:

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.0"
    },
    "configProperties": {
      "System.GC.CpuGroup": true,
      "System.GC.Server": true,
      "COMPlus_gcAllowVeryLargeObjects": 1
    }
  }
}

The property System.GC.CpuGroup seems to work, giving me a peak of ~28% CPU utilization by distributing threads across a single CPU Group:

CPU_usage

Now I need to distribute threads across different CPU Groups.

Thread_UseAllCpuGroups was omitted due to this documentation saying the variable is N/A in runtimeconfig.json, and must be set as an environment variable.

According to Trying to use Thread_UseAllCpuGroups in a .Net Core app this only works when set at the command line, but i have tried multiple ways of setting it:

  1. CommandLine using set COMPlus_Thread_UseAllCpuGroups=1 before running my program.
  2. Setting the variable though Control Panel -> System and Security -> System -> Environment Variables.
  3. Defining a launchSetting.json-file with the variable and copying it to the output directory.
  4. Manually setting the variable in my program.fs-file using System.Environment.SetEnvironmentVariable("COMPlus_Thread_UseAllCpuGroups", "1").

None of the above methods have worked, and I am unsure what I am doing wrong, especially given how few posts I can find online on this issue.

Finally my question is: How do I make my .NET 6 console application utilize all my logical processors?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions