Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.
1696 Discussions

how to get accurate number of cores/threads using cpuid on Core i7

erikcz
Beginner
1,537 Views
All the literature to which I've been exposed indicates that I can ascertain the number of cores on a package using:

CPUID.4.EAX[31:26]+1

and I have had great results on a broad spectrum of processors on which I've run my code.

But when I run the same code on my Core i7 820QM (which has 4 cores according to http://ark.intel.com/Product.aspx?id=43124 ), it indicates that there are 8 cores, not 4.

Similarly, the processor is supposed to have 8 total threads (per the same spec page linked above), but when I use the recommended cpuid call:

CPUID.1.EBX[23:16]

I get 16 threads instead of 8.

I'd heard that it was possible to infer similar information using CPUID.0Bh (thus accessing the x2apic processor topology functions), and while CPUID.0.EAX does yield "11", I also found reference that one could check if CPUID.1.ECX[21] to see if x2apic was enabled, but on my processor that bit is 0. Sure enough, calls to CPUID.0Bh with any value of ECX have EAX=0x0 and EBX=0x0.

Anyone know why I'm getting inconsistent results here?

I'm running the software on 64-bit Windows 7, using the __cpuid function from in Visual Studio 2008, e.g,:

// retrieve number of APIC IDs for the package ("cores")
int CPUInfo[4];
__cpuid(CPUInfo, 4);
return ((CPUInfo[0] & 0xfc000000) >> 26) + 1;

thanks
0 Kudos
3 Replies
janwassenberg
Beginner
1,537 Views

Welcome!

CPUID.4.EAX[31:26] is in fact the *maximum* number of APIC IDs for the package's cores.

You will need to enumerate all APIC IDs, split them into package/core/logical bitfields, and count how many unique 'core' values there are.
Code to do this may be found at http://trac.wildfiregames.com/browser/ps/trunk/source/lib/sysdep/arch/x86_x64/topology.cpp

As to the EAX=0xB failure, __cpuid may be rejecting 'InfoType' it doesn't know about. I would recommend another means of accessing CPUID, particularly because it doesn't seem possible to set ECX otherwise (how are you doing that?).

HTH+HAND
0 Kudos
erikcz
Beginner
1,537 Views
thanks, I'll take a look at the code and see.

As for passing ECX values, I'm using Microsoft's version __fastcall calling convention and passing my InfoType value as an argument to the method.
0 Kudos
janwassenberg
Beginner
1,537 Views
Ah. Some of the CPUID functions (0x4, 0xB) require the ECX register to be initialized with an additional index. This usage does not seem to be supported by __cpuid.
0 Kudos
Reply