【问题标题】:CPUID on multiple cores/NUMA多核/NUMA 上的 CPUID
【发布时间】:2012-01-23 23:38:16
【问题描述】:

我正在为我的爱好操作系统编写 CPU 检测和一般环境检测代码。是否存在需要多次调用 CPUID 的情况?那就是如果系统有多个核心,操作系统是否需要在每个核心上调用CPUID? NUMA 也一样。

AMDIntel CPUID 手册对此都不清楚。 osdev wiki 上有一篇文章提到调用 CPUID 称为 Detecting CPU Topology,但我的阅读并不清楚何时以及需要调用多少次 CPUID。

【问题讨论】:

  • 我认为 CPUID 可能出现异常行为的一种情况是 AMD Fusion,它在同一芯片上同时包含 CPU 和 GPU。您必须查看文档以获取更多信息。除此之外,我不明白为什么任何内部 CPU 内核会显示与另一个内核不同的 CPUID。
  • 除了给定的答案之外,多次调用 CPUID 的另一个原因是使用 rdtsc 指令进行性能测量时。您通常在 cpuid 之前使用它,因为 cpuid 是一个“序列化”指令并防止流水线操作,但 cpuid 也有一个讨厌的习惯,即在它被调用的前几次执行中花费更长的时间(根据 rdtsc 上的旧英特尔手册),所以它是典型的在启动时调用它几次以确保它被加速,然后在所有 rdtsc 调用之前使用它。

标签: x86 low-level osdev cpuid


【解决方案1】:

由于已经快一周了,没有人能够回答这个问题(可能是因为假期),我还是会尝试回答这个问题。

我认为答案是肯定的。您可能需要在每个内核上调用CPUID。原因之一是当今并非所有(甚至 x86)系统都是同构的。

例如,我在一个超频论坛上看到(我找不到链接),可以在某些双插槽服务器主板上混合两种不同处理器型号。这个人有一个带有两个不同速度处理器的双插槽 1366 系统。 (以及不同的型号)

因此,在这种情况下,调用 CPUID 将取决于线程所在的处理器 - 因此您需要在每个处理器上调用一次以获取所有信息。

在我的一个服务器主板的手册中,它还声明您可以混合使用不同型号的处理器(有一定的限制)。当然,可以混合使用同一处理器型号的两个不同的steppings


仅这个原因(异构拓扑),就已经是需要在每个内核上调用CPUID 的原因。

【讨论】:

  • 抱歉很久才回复,但是是的,我相信这是正确的。芯片上的每个 CPU 都需要提取和存储 CPUID 信息。
  • 那么如果你在每个 CPU 的每个核心上用不同的指令集成功调用 CPUID 会发生什么?即一个 CPU 有 SSSE3,另一个 SSSE4.2。然后,您使用此信息决定输入一段使用 SSE4.2 指令的代码。在执行此代码的过程中,操作系统会换出您的线程,然后将其安排在仅支持 SSSE3 的 CPU 上。然后代码在执行 SSE4.1 指令时崩溃。所以即使在多核上调用 CPUID 也是不够的,还必须在这样做之后设置线程亲和性。这是正确的吗?
  • @Apriori 这听起来极不可能。我知道单个 Intel 或 AMD x86 配置可以让您使用不同的指令集安装来自不同代的不同 CPU。但是,如果您想过分小心,是的,您可以这样做。不过我认为这有点矫枉过正。
  • 我认为这种方法听起来有点偏执,但总有一天它可能会成为一个“有趣”的崩溃转储。我读过的所有描述如何使用 CPUID 指令的解释都没有提到关于多进程/核心场景的任何内容。但似乎它可能比大多数使用 x86 SIMD 的开发人员意识到的更大。我不清楚的另一件事是天气最好在每次代码可能分支时调用 CPUID,或者一次并缓存结果。 Agner Fog 在 Sandy Bridge 上的 CPUID 为 100 到 250 个周期延迟。我离题了,这可能需要一个新问题;我很高兴发布。
  • @Apriori 更正我最后的评论。 “我知道”。我不知何故放弃了这个词。简而言之,我认为不可能构建一个处理器具有不同指令集的系统。我想这在虚拟机内部是可能的,但那只是要求它。
猜你喜欢
  • 2015-02-28
  • 2013-05-27
  • 2015-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 2017-01-19
  • 1970-01-01
相关资源
最近更新 更多