5

好的,所以我在 C# 中发布 GetEnvironmentVariable("NUMBER_OF_PROCESSORS") 返回错误的数字,询问如何在 C# 中获取正确的内核数。一些乐于助人的人向我提出了一些类似问题的问题,但我已经尝试过这些解决方案。然后我的问题被关闭,因为它与另一个问题相同,这是真的,但那里给出的解决方案不起作用。所以我正在打开另一个,希望有人能够帮助意识到其他解决方案不起作用。

那个问题是如何通过 .NET/C# 找到 CPU 核心数?它使用 WMI 来尝试获得正确数量的内核。好吧,这是那里给出的代码的输出:

Number Of Cores: 32
Number Of Logical Processors: 32
Number Of Physical Processors: 4

根据我的最后一个问题,该机器是运行 Windows Server 2008 R2 HPC 版本的 64 核 AMD Opteron 6276(4x16 核)。

不管我做什么,Windows 似乎总是返回 32 个内核,即使有 64 个内核可用。我已经确认机器只使用了 32 个内核,如果我硬编码 64 个内核,那么机器会使用所有内核。我想知道检测 AMD CPU 的方式是否可能存在问题。

仅供参考,如果您还没有阅读最后一个问题,如果我在命令行中键入 echo %NUMBER_OF_PROCESSORS",它会返回 64。它不会在编程环境中执行此操作。

谢谢,贾斯汀

更新:输出 PROCESSOR_ARCHITECTURE 从命令行返回 AMD64,但从程序返回 x86。该程序是在 64 位硬件上运行的 32 位程序。我被要求将其编译为 64 位,但它仍然显示 32 个内核。

4

2 回答 2

7

感谢您的帮助,但我找到了问题所在。正如我所料,这是由于 AMD 的设计。他们正在使用一种称为 MCM(我认为是多芯片模块)的新架构,这会导致 Windows 无法正确识别内核数量。我将此作为解决方案发布,以防其他人遇到它。一位同事指导我使用http://support.microsoft.com/kb/2711085上提供的修补程序

于 2012-07-23T04:40:31.743 回答
3

在 Windows 7/Windows Server 2008 R2之前,逻辑处理器的最大数量限制为 CPU 寄存器的大小:32 位操作系统为 32,64 位系统为 64。这是因为对单个寄存器大小的值进行原子操作很容易。

为了与假定处理器数量永远不会超过 32 的 32 位应用程序兼容,返回的SYSTEM_INFO结构的结构上限为 32。32 位进程可以调用以获取 64 位视图。.NET 的属性调用.dwNumberOfProcessorsGetSystemInfoGetNativeSystemInfoEnvironment.ProcessorCountGetSystemInfo

Windows 7/2008 R2 使用更新的内核,将支持的处理器内核数量从 64 个更改为 256 个,并取消了一些内核锁定。为了与旧应用程序兼容,Windows 7 引入了处理器组的概念。所有处理处理器掩码的旧 API 现在都在进程内的处理器上运行,而不是在所有处理器上运行。对于 64 个或更少的处理器,只有一组,但 Windows 7 最多支持 4 组。Windows 8/Server 2012 支持 10 个。(32 位操作系统不能使用超过 32 个逻辑处理器,并且总是一组。)如果你想知道实际的核心数量和它们的排列,你必须调用GetActiveProcessorCount.

我找不到任何明确说明的信息,但NUMBER_OF_PROCESSORS出于同样的原因,我预计会受到限制,并且 32 位进程的环境上限为 32。

Windows Server 2008 R2 确实是用词不当。这意味着与 Windows Server 2008 相比,Windows 核心的变化很小,但事实并非如此。

于 2012-12-03T17:01:49.577 回答