【问题标题】:Using CPUID to detect CPU specs, reliable solution?使用 CPUID 检测 CPU 规格,可靠的解决方案?
【发布时间】:2012-03-05 01:13:07
【问题描述】:

我正在尝试使用__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() 真的可靠吗?根据我自己的经验,它似乎并不那么可靠。我有什么非常根本的错误吗?

【问题讨论】:

  • 如果你不打算使用 __cpuid()。您可以使用 OpenMPs omp_get_num_procs() 它应该返回您的 CPU 可以同时运行的线程数量。我不知道这些信息有多可靠。这种方式我从来没有遇到过任何问题。
  • CPUID 通常相当可靠,但有时它可能会产生误导或不正确。您的 CPU 可能很好地支持一项功能,但您的主板不支持(或已禁用),因此它会被报告为存在,但无法正常工作。有一些库采用 CPUID 并尝试使其更可靠,并带有更正数据库等。
  • 但是如果 CPU 不支持超线程和 CPUID 给你它存在的信息是主板的真正问题,我可以看到它是相反的,CPU 支持HTT 但不是主板,因此在检查 HTT 时会出现错误。

标签: cpu cpuid


【解决方案1】:

几乎可以肯定,您的处理器上的 [x2]APIC id 存在差距,这意味着 APIC id 的某些值不会映射到任何逻辑处理器。您应该使用 cpuid 的 0xB 叶来找出答案。您可以查看参考 Intel 代码和算法 (https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/) 的步骤,但它归结为使用 EAX=0xB、ECX=0 调用并在 EBX 中获取每个内核的逻辑处理器(线程)数,然后调用cpuid 再次使用 EAX=0xB,ECX=1 并在 EBX 中获取每个处理器包的逻辑处理器数。

使用叶子 0x1 的旧方法无法解决 APIC id 差距。唉,这仍然是 MSDN Visual C++ 2013 参考页面 (http://msdn.microsoft.com/en-us/library/hskdteyh.aspx) 上给出的示例代码,它对于 2010 年及之后制造的处理器是不正确的,因为您发现是否使用来自MSDN 或其他地方的类似错误代码。 cpuid 上的 Wikipedia 页面,我最近在努力理解这个问题后进行了更新,现在在“英特尔线程/核心和缓存拓扑”部分中有一个已解决的示例,用于枚举具有 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 拓扑,可靠的解决方案吗?”因为我完全偶然发现了你的问题。当我发现你的问题时,我正在谷歌上搜索 Sandy Bridge cpuid 转储。

【讨论】:

    【解决方案2】:

    CPUID 是可以信任的,你只需要正确使用它。在这种情况下,这意味着正确地枚举拓扑。你得到 16 个逻辑处理器,因为它得到的字段代表它可以支持的最大值,而不是实际有多少。为核心检索的值实际上是逻辑计数。

    主题中的代码非常基础,作为起点,在我的系统 (i7 2720QM) 上,我也记录了无效数据,但是使用我自己的代码根据 Intel CPUID 映射检查拓扑,我得到正确的结果.

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多