views:

414

answers:

1

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?

A: 

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.

PhiS