X86 多核上的CPUID/NUMA

X86 多核上的CPUID/NUMA,x86,low-level,osdev,cpuid,X86,Low Level,Osdev,Cpuid,我正在为我的爱好操作系统编写CPU检测和通用环境检测代码。是否存在需要多次调用CPUID的情况?也就是说,如果系统有多个内核,那么操作系统是否需要在每个内核上调用CPUID?努马也一样 关于这一点,CPUID和CPUID手册都不清楚。osdev wiki上有一篇文章提到调用CPUID,但据我所知,CPUID需要调用的时间和次数并不清楚。因为已经快一周了,没有人能够回答这个问题(可能是因为假期),我还是会尝试回答这个问题 我认为答案是肯定的。您可能需要在每个核心上调用CPUID。其中一个原因是,今

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


关于这一点,CPUID和CPUID手册都不清楚。osdev wiki上有一篇文章提到调用CPUID,但据我所知,CPUID需要调用的时间和次数并不清楚。

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

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

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

因此,在本例中,调用
CPUID
将取决于线程所在的处理器-因此您需要在每个处理器上调用它一次,以获取所有信息

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



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

我想CPUID可能会异常工作的一种情况是AMD Fusion,它在同一个芯片上同时包含CPU和GPU。您必须查看文档以了解更多信息。除此之外,我不明白为什么任何内部CPU内核都会显示与另一个内核不同的CPUID。除了给出的答案外,多次调用CPUID的另一个原因是在使用rdtsc指令进行性能测量时。因为cpuid是一个“序列化”指令,它会阻止管道传输,所以通常在调用之前使用cpuid,但cpuid也有一个讨厌的习惯,即在调用前几次执行cpuid需要花费更长的时间(根据旧的英特尔rdtsc手册),所以启动时通常会调用cpuid几次,以确保加快速度,然后在你所有的rdtsc呼叫之前使用它。很抱歉回复时间太长,但我相信这是正确的。芯片上的每个CPU都需要提取和存储CPUID信息。因此,如果您使用不同的指令集在每个CPU的每个内核上成功调用CPUID,会发生什么;i、 e.一个CPU具有SSSE3,另一个CPU具有SSSE4.2。然后使用此信息决定输入使用SSE4.2指令的代码段。在执行这段代码的过程中,操作系统会跳出你的线程,接下来它被安排在只支持SSSE3的CPU上。然后代码在执行SSE4.1指令时崩溃。因此,在多个内核上调用CPUID是不够的,甚至必须在这样做之后设置线程亲缘关系。这是正确的吗?@Apriori,听起来极不可能。我知道一个单一的Intel或AMD x86配置将允许您使用不同的指令集安装不同代的不同CPU。但是如果你想过分小心,是的,你可以这样做。不过我觉得这太过分了。我觉得这种方法听起来有点偏执,但总有一天它会成为一个“有趣的”坠机垃圾场。我读过的所有描述如何使用CPUID指令的解释都没有提到关于多进程/核心场景的任何内容;但这似乎比大多数使用x86 SIMD的开发人员意识到的问题更大。另一件我不清楚的事情是,是否最好在每次代码可能分支时调用CPUID,或者一次调用CPUID并缓存结果。Agner Fog在Sandy Bridge上的CPUID延迟为100到250个周期。我离题了,这可能需要一个新的问题;这是我很高兴发布的。@Apriori更正我的最后一个评论。“我不知道”。不知怎的,我把那个词忘了。简言之,我认为不可能构建一个处理器具有不同指令集的系统。我想这在虚拟机中是可能的,但那只是要求而已。