Ok, so I posted in In C# GetEnvironmentVariable("NUMBER_OF_PROCESSORS") returns the wrong number asking about how to get the correct number of cores in C#. Some helpful people directed me to a couple of questions where similar questions were asked but I have already tried those solutions. My question was then closed as being the same as another question, which is true, it is, but the solution given there didn't work. So I'm opening another one hoping that someone may be able to help realising that the other solutions DID NOT work.
That question was How to find the Number of CPU Cores via .NET/C#? which used WMI to try to get the correct number of cores. Well, here's the output from the code given there:
Number Of Cores: 32
Number Of Logical Processors: 32
Number Of Physical Processors: 4
As per my last question, the machine is a 64 core AMD Opteron 6276 (4x16 cores) running Windows Server 2008 R2 HPC edition.
Regardless of what I do Windows always seems to return 32 cores even though 64 are available. I have confirmed the machine is only using 32 and if I hardcode 64 cores, then the machine uses all of them. I'm wondering if there might be an issue with the way the AMD CPUs are detected.
FYI, in case you haven't read the last question, if I type echo %NUMBER_OF_PROCESSORS" at the command line, it returns 64. It just won't do it in a programming environment.
Thanks, Justin
UPDATE: Outputting PROCESSOR_ARCHITECTURE returns AMD64 from the command line, but x86 from the program. The program is 32-bit running on 64-bit hardware. I was asked to compile it to 64-bit but it still shows 32 cores.
Thanks for your assistance, but I've found the problem. As I expected, it was due to AMDs design. They're using a new architecture called MCM (multi chip module I think) that causes Windows to not correctly identify the number of cores. I'm posting this as a solution in case anyone else runs into it. A work collegue directed me to a hotfix available at http://support.microsoft.com/kb/2711085
Before Windows 7/Windows Server 2008 R2, the maximum number of logical processors was limited to the size of a CPU register: 32 for the 32-bit operating system, 64 for the 64-bit system. This was because it's easy to do atomic operations on a single register-sized value.
For compatibility with 32-bit applications that assumed the number of processors could never be more than 32, the SYSTEM_INFO
structure's dwNumberOfProcessors
structure returned by GetSystemInfo
was capped at 32. A 32-bit process can call GetNativeSystemInfo
to get the 64-bit view. .NET's Environment.ProcessorCount
property calls GetSystemInfo
.
Windows 7/2008 R2 use an updated kernel that changes the number of supported processor cores from 64 to 256, and does away with some of the core locks. For compatibility with older applications, Windows 7 introduces the concept of a processor group. All the old APIs that dealt with processor masks now operate on the processors within the process's group, rather than on all processors. With 64 processors or fewer, there is only one group, but Windows 7 supports up to 4 groups. Windows 8/Server 2012 supports 10. (The 32-bit OS cannot use more than 32 logical processors, and always has one group.) If you want to find out the actual number of cores and their arrangement, you have to call GetActiveProcessorCount
.
I can't find any information explicitly saying so, but I would expect NUMBER_OF_PROCESSORS
to be capped for the same reason, and that a 32-bit process would be given an environment capped at 32.
Windows Server 2008 R2 is really a misnomer. It implies that there are minimal changes in the core of Windows compared to Windows Server 2008, and that just isn't true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With