Using CPUID to detect CPU specs, reliable solution?
Asked Answered
A

2

7

I'm trying to gather information about my CPU with __cpuid(). Though it is getting it right on my computer, when I run my program on my colleague's computer it is detecting the Intel Core2 Quad Q6600 to be hyper-threaded, though according to the specifications on Intel's own site it isn't.

__cpuid() is also detecting the wrong amount of "logical cores" as can be shown here: Programmatically detect number of physical processors/cores or if hyper-threading is active on Windows, Mac and Linux. Where it claims that the Intel Xeon E5520 has 16 logical cores and 8 physical.

I tried running the code found in that thread on my own computer, a Intel i7 2600K giving me the same numbers as for the Xeon.

So how reliable is __cpuid() really? From my own experience it doesn't seem to be that reliable. Have I got something very fundamental wrong?

Adahadaha answered 13/2, 2012 at 16:12 Comment(3)
If you are not bent on using __cpuid(). You could use OpenMPs omp_get_num_procs() which should return the amount of threads your CPU can run simultaneously. I've no idea on how reliable this information is. I never had any problems this way.Stereochemistry
CPUID is generally fairly reliable, but, sometimes it can be misleading or incorrect. Your CPU might very well support one feature, but your motherboard doesn't (or has it disabled), so it will be reported as present, but not work. There are libraries out there that take CPUID and try to make it a bit more reliable, with a database of corrections and such.Cheque
But if the CPU doesn't support Hyperthreading and CPUID giving you the information that it is present is that really an issue with the motherboard, I could see it being the otherway around, where the CPU is supporting HTT but not the motherboard and therfore you get a false when checking for HTT.Adahadaha
T
6

There is almost certainly a gap in the [x2]APIC ids on your processor, meaning that some value of the APIC ids don't map to any logical processors. You should use the 0xB leaf of cpuid to find out. You can look at the reference Intel code and algorithm (https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/) for the steps, but it broils down to calling with EAX=0xB, ECX=0 and obtaining in EBX the number of logical processors (threads) per core and then calling cpuid again with EAX=0xB, ECX=1 and getting in EBX the number of logical processors per processor package.

The old method of using leaf 0x1 cannot account for APIC id gaps. Alas that's the sample code still given on the MSDN Visual C++ 2013 reference page (http://msdn.microsoft.com/en-us/library/hskdteyh.aspx), and it is incorrect for processors made in 2010 and thereafter, as you found out whether by using the code from MSDN or similarly incorrect code from elsewhere. The Wikipedia page on cpuid, which I've recently updated after struggling myself to understand the issue, now has a worked out example in the section on "Intel thread/core and cache topology" for enumerating topology on a processor with APIC id gaps, with additional details, including how to determine which bits of the APIC ids are actually used and which are "dead".

Given the code sample currently offered by Microsoft on their __cpuid() page, this is basically the same question as Logical CPU count return 16 instead of 4 because it's rooted in the same interpretation error of the Intel specs. As an explanation for MSDN's poor show, the code they offer worked okay before 2010 or so; Intel used to provide a similar method before the x2APIC was introduced as you can see in this old video/article: https://software.intel.com/en-us/articles/hyper-threading-technology-and-multi-core-processor-detection If you look at the various versions of the MSDN page on __cpuid, their code sample has basically remained the same since 2008...

As for the single hyperthreaded detection bit, that is a longer story, already answered by me at Why does Hyper-threading get reported as supported on processors without it?. The nutshell is that that rather legacy bit tells you if the processor package supports more than one logical processor, be it via hypethreading or multi-core technology. The name of the bit is thus rather misleading.

Also, I suggest changing the title of you question to "Using CPUID to detect CPU topology, reliable solution?" because I've found your question completely by accident. I was searching for Sandy Bridge cpuid dumps on google when I found your question.

Toxicosis answered 11/7, 2014 at 13:50 Comment(0)
H
3

CPUID can be trusted, you just need to use it correctly. in this case, it means enumerating the topology correctly. you get 16 logical processors because the field its gotten from represents the maximum it can support, not how many there actually are. the value retrieved for cores is actually the logical count.

the code in the topic is very basic and meant as a starting point, on my system (i7 2720QM) i also record invalid data, but using my own code that checks the topology as per Intel CPUID mappings, I get correct results.

Hereabout answered 13/2, 2012 at 21:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.