I'd try f# issues page:
How do I configure my multithreaded .NET 6 application to use all Windows CPU groups?
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:
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:
- CommandLine using
set COMPlus_Thread_UseAllCpuGroups=1
before running my program. - Setting the variable though
Control Panel -> System and Security -> System -> Environment Variables
. - Defining a
launchSetting.json
-file with the variable and copying it to the output directory. - Manually setting the variable in my
program.fs
-file usingSystem.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?