Skip to content

Commit e42de0e

Browse files
authored
Update Environment.ProcessorCount on Windows to take into account the processor affinity mask (#45943)
- Similarly to cases on Unixes where sched_getaffinity is available - If `GCCpuGroup` and `Thread_UseAllCpuGroups` are both enabled, I'm not sure if the `CPUGroupInfo` count of active processors takes affinity into account as the docs are not clear, for now I'm not modifying that path until I can verify it - Otherwise, a process that is started with a specific processor affinity mask still shows full CPU count - This is one of the differences in the portable managed thread pool implementation, which relies on Environment.ProcessorCount, as opposed to the native thread pool, which uses the affinity mask - After this change, in affinitized cases on Windows the behavior is consistent perf-wise with Linux in similar situations: - The portable thread pool uses the same worker thread count as the native thread pool - `Environment.ProcessorCount` returns the number of processors the the process is affinitized to, which may be less than it would have returned before
1 parent 6959d98 commit e42de0e

File tree

4 files changed

+17
-42
lines changed

4 files changed

+17
-42
lines changed

src/coreclr/classlibnative/bcltype/system.cpp

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -185,29 +185,19 @@ INT32 QCALLTYPE SystemNative::GetProcessorCount()
185185
#ifndef TARGET_UNIX
186186
CPUGroupInfo::EnsureInitialized();
187187

188-
if(CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
188+
if (CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
189189
{
190190
processorCount = CPUGroupInfo::GetNumActiveProcessors();
191191
}
192+
else
192193
#endif // !TARGET_UNIX
193-
// Processor count will be 0 if CPU groups are disabled/not supported
194-
if(processorCount == 0)
195194
{
196-
SYSTEM_INFO systemInfo;
197-
ZeroMemory(&systemInfo, sizeof(systemInfo));
198-
199-
GetSystemInfo(&systemInfo);
200-
201-
processorCount = systemInfo.dwNumberOfProcessors;
195+
// This similar to GetSystemInfo() + dwNumberOfProcessors except:
196+
// - GetCurrentProcessCpuCount() tries to take into account the processor affinity mask where applicable
197+
// - GetCurrentProcessCpuCount() on Unixes tries to take into account cgroups CPU quota limits where applicable
198+
processorCount = GetCurrentProcessCpuCount();
202199
}
203200

204-
#ifdef TARGET_UNIX
205-
uint32_t cpuLimit;
206-
207-
if (PAL_GetCpuLimit(&cpuLimit) && cpuLimit < (uint32_t)processorCount)
208-
processorCount = cpuLimit;
209-
#endif
210-
211201
END_QCALL;
212202

213203
return processorCount;

src/coreclr/inc/utilcode.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,6 @@ class CPUGroupInfo
12781278
static BOOL m_threadAssignCpuGroups;
12791279
static WORD m_initialGroup;
12801280
static CPU_Group_Info *m_CPUGroupInfoArray;
1281-
static bool s_hadSingleProcessorAtStartup;
12821281

12831282
static BOOL InitCPUGroupInfoArray();
12841283
static BOOL InitCPUGroupInfoRange();
@@ -1309,13 +1308,6 @@ class CPUGroupInfo
13091308
static void ClearCPUGroupAffinity(GROUP_AFFINITY *gf);
13101309
static BOOL GetCPUGroupRange(WORD group_number, WORD* group_begin, WORD* group_size);
13111310
#endif
1312-
1313-
public:
1314-
static bool HadSingleProcessorAtStartup()
1315-
{
1316-
LIMITED_METHOD_CONTRACT;
1317-
return s_hadSingleProcessorAtStartup;
1318-
}
13191311
};
13201312

13211313
DWORD_PTR GetCurrentProcessCpuMask();

src/coreclr/utilcode/util.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,6 @@ BYTE * ClrVirtualAllocWithinRange(const BYTE *pMinAddr,
856856
/*static*/ WORD CPUGroupInfo::m_initialGroup = 0;
857857
/*static*/ CPU_Group_Info *CPUGroupInfo::m_CPUGroupInfoArray = NULL;
858858
/*static*/ LONG CPUGroupInfo::m_initialization = 0;
859-
/*static*/ bool CPUGroupInfo::s_hadSingleProcessorAtStartup = false;
860859

861860
#if !defined(FEATURE_REDHAWK) && (defined(TARGET_AMD64) || defined(TARGET_ARM64))
862861
// Calculate greatest common divisor
@@ -1014,18 +1013,6 @@ DWORD LCM(DWORD u, DWORD v)
10141013
m_threadUseAllCpuGroups = threadUseAllCpuGroups && hasMultipleGroups;
10151014
m_threadAssignCpuGroups = threadAssignCpuGroups && hasMultipleGroups;
10161015
#endif // TARGET_AMD64 || TARGET_ARM64
1017-
1018-
// Determine if the process is affinitized to a single processor (or if the system has a single processor)
1019-
DWORD_PTR processAffinityMask, systemAffinityMask;
1020-
if (GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask))
1021-
{
1022-
processAffinityMask &= systemAffinityMask;
1023-
if (processAffinityMask != 0 && // only one CPU group is involved
1024-
(processAffinityMask & (processAffinityMask - 1)) == 0) // only one bit is set
1025-
{
1026-
s_hadSingleProcessorAtStartup = true;
1027-
}
1028-
}
10291016
}
10301017

10311018
/*static*/ BOOL CPUGroupInfo::IsInitialized()

src/coreclr/vm/eeconfig.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -899,12 +899,18 @@ fTrackDynamicMethodDebugInfo = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_
899899

900900
tieredCompilation_CallCountingDelayMs = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCountingDelayMs);
901901

902+
bool hasSingleProcessor;
902903
#ifndef TARGET_UNIX
903-
bool hadSingleProcessorAtStartup = CPUGroupInfo::HadSingleProcessorAtStartup();
904-
#else // !TARGET_UNIX
905-
bool hadSingleProcessorAtStartup = g_SystemInfo.dwNumberOfProcessors == 1;
906-
#endif // !TARGET_UNIX
907-
if (hadSingleProcessorAtStartup)
904+
if (CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
905+
{
906+
hasSingleProcessor = CPUGroupInfo::GetNumActiveProcessors() == 1;
907+
}
908+
else
909+
#endif
910+
{
911+
hasSingleProcessor = GetCurrentProcessCpuCount() == 1;
912+
}
913+
if (hasSingleProcessor)
908914
{
909915
DWORD delayMultiplier = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_DelaySingleProcMultiplier);
910916
if (delayMultiplier > 1)

0 commit comments

Comments
 (0)