我正在尝试使用__cpuid()
收集有关我的CPU的信息。虽然它在我的计算机上运行正常,但当我在我的同事的计算机上运行我的程序时,它检测到Intel Core2 Quad Q6600是超线程的,尽管根据英特尔自己网站上的规范它不是。
__cpuid()
也检测到错误数量的“逻辑核心”,如下所示:
Programmatically detect number of physical processors/cores or if hyper-threading is active on Windows, Mac and Linux。它声称Intel Xeon E5520有16个逻辑核心和8个物理核心。
我尝试在我自己的计算机上运行该线程中的代码,Intel i7 2600K给我的数字与Xeon相同。
__cpuid()
真的有多可靠?根据我自己的经验,它似乎并不那么可靠。我有一些非常根本的错误吗?
答案 0 :(得分:3)
CPUID可以信任,您只需要正确使用它。在这种情况下,它意味着正确枚举拓扑。你得到16个逻辑处理器,因为它得到的字段代表它可以支持的最大值,而不是实际有多少。为核心检索的值实际上是逻辑计数。
主题中的代码非常基本,并且作为一个起点,在我的系统(i7 2720QM)上我也记录了无效数据,但是使用我自己的代码来检查拓扑,根据Intel CPUID映射,我得到了正确的结果
答案 1 :(得分:2)
处理器上的[x2] APIC ID几乎肯定存在差距,这意味着APIC ID的某些值不会映射到任何逻辑处理器。您应该使用cpuid的0xB叶子来查找。您可以查看参考英特尔代码和算法(https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/)的步骤,但它可以归结为调用EAX = 0xB,ECX = 0并在EBX中获取每个核心的逻辑处理器(线程)数量然后再次使用EAX = 0xB,ECX = 1调用cpuid,并获得每个处理器包的逻辑处理器数量。
使用叶子0x1的旧方法无法解释APIC id间隙。唉,仍然是在MSDN Visual C ++ 2013参考页面(http://msdn.microsoft.com/en-us/library/hskdteyh.aspx)上给出的示例代码,而对于2010年及之后的处理器是不正确的,正如您发现的那样是否使用来自MSDN的代码或来自其他地方的类似错误代码。关于cpuid的维基百科页面,我在努力了解这个问题后最近更新了,现在在“英特尔线程/核心和缓存拓扑”这一部分中有一个成功的例子。用于枚举具有APIC id间隙的处理器上的拓扑,以及其他详细信息,包括如何确定实际使用哪些APIC ID以及哪些是"死"。
鉴于Microsoft目前在其__cpuid()页面上提供的代码示例,这与Logical CPU count return 16 instead of 4基本相同,因为它的根源在于英特尔规范的相同解释错误。作为MSDN糟糕节目的解释,他们提供的代码在2010年之前就可以正常使用;在介绍x2APIC之前,英特尔过去常常提供类似的方法,正如您在这篇旧视频/文章中看到的那样:https://software.intel.com/en-us/articles/hyper-threading-technology-and-multi-core-processor-detection如果您查看__cpuid上各种版本的MSDN页面,他们的代码示例基本保持不变自2008年以来......
对于单个超线程检测位,这是一个较长的故事,我已在Why does Hyper-threading get reported as supported on processors without it?回答。简而言之,相当传统的位告诉您处理器包是否支持多个逻辑处理器,无论是通过超线程还是多核技术。因此,该位的名称相当误导。
另外,我建议将问题的标题更改为"使用CPUID检测CPU 拓扑,可靠的解决方案?"因为我完全是偶然发现了你的问题。当我发现你的问题时,我在google上搜索Sandy Bridge cpuid转储。