6

我在基于 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 重复。

有没有人遇到过这个问题?

4

1 回答 1

5

有趣的问题 - 不幸的是我没有 i7 可以玩,所以我只能在这里猜测。

看看这篇文章可能会很有用——虽然原则上你的方法似乎是正确的,但它们提出了一些警告。也许阅读一下,看看在任何阶段您的任何假设是否可能是错误的。它们本质上使用 CPUID.1.EBX[23:16](物理包中的最大日志处理器数)、CPUID.4.EAX[31:26]+1(物理包中的最大内核数)和 CPUID.4 .EAX[25:14]+1(共享目标级别缓存的物理包中的最大日志处理器数)来推断处理器拓扑 - 这与您正在做的事情一致。

其次,作为替代方案,在支持 CPUID 函数 EAX = 0Bh 的 CPU 上(请参阅此处的英特尔文档),您可以使用此函数来获取所需的规格。也许比较这两种方法的结果可能很有启发性?

--Edit-- 是一篇非常有用的文章,涵盖了上述两种方法。本质上,我认为在 i7 上,CPUID.0B 是首选变体。

于 2009-11-04T11:56:34.947 回答