Intel i7 处理器上的 CPUID
我在较新的基于 i7 的计算机上遇到基于 CPUID 的代码的问题。它检测到 CPU 为具有 8 个 HT 单元的单核,而不是每个具有 2 个 HT 单元的 4 个核。
我一定是误解了从 CPU 返回的 CPUID 信息的结果,但我不明白是怎么回事。
基本上,我会遍历 Windows 可见的每个处理器,设置与该线程的线程关联性,然后进行一系列 CPUID 调用。
args = new CPUID_Args();
args.eax = 1;
executeHandler(ref args);
if (0 != (args.edx & (0x1 << 28)))
{
//If the 28th bit in EDX is flagged, this processor supports multiple logical processors per physical package
// in this case bits 23:16 of EBX should give the count.
//** EBX here is 0x2100800
logicalProcessorCount = (args.ebx & 0x00FF0000) >> 16;
//** this tells me there are 16 logical processors (wrong)
}
else
{ logicalProcessorCount = 1; }
apic = unchecked((byte)((0xFF000000 & args.ebx) >> 24));
if (maximumSupportedCPUID >= 4)
{
args = new CPUID_Args();
args.eax = 4;
executeHandler(ref args);
//EAX now contains 0x1C004121
coreCount = 1 + ((args.eax & 0xFC000000) >> 26);
//This calculates coreCount as 8
}
else
{ coreCount = 1; }
对系统中其余的 CPU 重复此序列。
以前有人遇到过这个吗?
I'm having an issue with my CPUID-based code on newer i7-based machines. It is detecting the CPU as having a single core with 8 HT units instead of 4 cores each with 2 HT units.
I must be misinterpreting the results of the CPUID information coming back from the CPU, but I can't see how.
Basically, I iterate through each processor visible to Windows, set thread affinity to that thread and then make a sequence of CPUID calls.
args = new CPUID_Args();
args.eax = 1;
executeHandler(ref args);
if (0 != (args.edx & (0x1 << 28)))
{
//If the 28th bit in EDX is flagged, this processor supports multiple logical processors per physical package
// in this case bits 23:16 of EBX should give the count.
//** EBX here is 0x2100800
logicalProcessorCount = (args.ebx & 0x00FF0000) >> 16;
//** this tells me there are 16 logical processors (wrong)
}
else
{ logicalProcessorCount = 1; }
apic = unchecked((byte)((0xFF000000 & args.ebx) >> 24));
if (maximumSupportedCPUID >= 4)
{
args = new CPUID_Args();
args.eax = 4;
executeHandler(ref args);
//EAX now contains 0x1C004121
coreCount = 1 + ((args.eax & 0xFC000000) >> 26);
//This calculates coreCount as 8
}
else
{ coreCount = 1; }
This sequence repeats for the remainder of the CPUs in the system.
Has anyone faced this before?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有趣的问题 - 不幸的是我没有 i7 可以玩,所以我只能在这里猜测。
查看这篇文章 - 虽然原则上你的方法似乎是正确的,但他们提出了一些警告。也许读一读,看看您的任何假设是否在任何阶段都可能是错误的。它们本质上使用 CPUID.1.EBX[23:16](物理包中的最大日志处理器数)、CPUID.4.EAX[31:26]+1(物理包中的最大内核数)和 CPUID.4 .EAX[25:14]+1(共享目标级别缓存的物理包中的最大日志处理器数)来推断处理器拓扑 - 这与您正在做的事情一致。
其次,作为替代方案,在支持 CPUID 功能 EAX = 0Bh 的 CPU 上(请参阅 英特尔的文档在这里),您可以使用此函数来获取您想要的规格。也许比较两种方法的结果可能会有所启发?
- 编辑 -
这是一篇非常有用的文章它涵盖了上述两种方法。本质上,我认为在 i7 上,CPUID.0B 是首选变体。
Interesting question - unfortunately I don't have an i7 to play with, so I can only guess here.
It may be useful to have a look at this article - while in principle your approach seems correct, they state a few caveats. Maybe have a read and see whether at any stage any of your assumptions may be wrong. They essentially use CPUID.1.EBX[23:16] (max # log processors in a physical package), CPUID.4.EAX[31:26]+1 (max # of cores in a physical package) and CPUID.4.EAX[25:14]+1 (max # of log processors in a physical package sharing the target level cache) to infer the processor topology - which is along the lines of what you're doing.
Secondly, as an alternative, on a CPU which supports the CPUID function EAX = 0Bh (see Intel's docs here), you may use this function instead to get the specs you want. Maybe comparing the results of the two approaches may be illuminating?
--Edit--
This is a very useful article which covers both of the approaches above. Essentially, I gather that on an i7, CPUID.0B is the preferred variant.