Logical CPU count return 16 instead of 4
Asked Answered
Q

2

2

I have a Intel Core i5-2450m (2 physical processors and 4 logical processors) and I want to find a way to count logical and physical cores on AMD and Intel CPUs. But, after some searches I noticed something strange. Instead of returning 4 logical units, my code give me 16.

static int8_t LogicalProcCount(void)
{
    if ( !Hyperthreading )
        return 1;

    uint32_t unused, ebx;
    CPUID(1, unused, ebx, unused, unused);

    return (int8_t) ( (ebx >> 16 ) & 0xFF );
}
Quadricycle answered 6/6, 2014 at 18:56 Comment(7)
What CPUID macro/function are you using there? Are you sure you don't need to pass the output variables by address and not by value?Gunyah
@Elliott I agree with your interpretation, but I bet OP misspoke. The i5-2450m is a dual-core, 4 thread part. ark.intel.com/products/53452/…Meloniemelony
@pushd when you say "2 physical processors" that means two chips sitting in two sockets. It sounds like you mean "2 cores" and "4 threads" (i.e. 2-way hyperthreading).Meloniemelony
Where is this CPUID coming from? That's not the name of the compiler-provided instrinsic function, so it must be some non-standard wrapper.Beeswax
@BenVoigt It is a non-standard wrapper.Dredge
@ElliottFrisch That can't be the explanation. CPUID gives you the information for whatever physical processor it gets run on. It does not account for other physical CPUs in the system.Gunyah
@AndrewMedico It's reading the maximum number of APIC(s) assignable to the logical processors in that physical package, as per the answer below.Swarts
D
6

CPUID.1:EBX[23:16] represents the maximum number of addressable IDs (initial APIC ID) that can be assigned to logical processors in a physical package.

Source.

So 16 has nothing to do with the actual number of your logical CPUs. On my machine CPUID.1:EBX[23:16] also returns 16, though it has 8 logical CPUs.

Sample code to count actual logical CPUs can be also found in the linked whire paper.

Dredge answered 6/6, 2014 at 19:35 Comment(1)
The source link brokeRecant
K
2

A more complete answer would be that for Intel processors made before 2010 that kind code was usually okay. (I'd like to hear about counter-examples though!) That kind of counting routine was even given in an older Intel presentation dating to 2007(?) or so https://software.intel.com/en-us/articles/hyper-threading-technology-and-multi-core-processor-detection (Don't let the posting date the fool you; when that presentation was made the Intel Core wasn't yet public and the Pentium Extreme Edition was Intel's top offering.) Rather shamefully, that algorithm is still given in the MSDN page about __cpuid, even for their 2013 edition! (http://msdn.microsoft.com/en-us/library/hskdteyh.aspx) The MSDN sample code hasn't been updated since 2008...

In early 2010 Intel put out Westmere processors that have gaps in their APIC id space. So these and later processors need a more refined method of counting their cores. These processors all have x2APIC and support leaf 0xB of cpuid as well... which can tell you about the gaps in the APIC id space, via EAX[4:0] and exactly how many logical processors are present at each level (package/core) via EBX. The link provided by n.m. is the authoritative one, albeit rather dry. Basically all you have to do is call cpuid with EAX=0xB, ECX=1 and you'll have the correct number of logical processors per package returned in EBX.

Also, the part of question about AMD was not answered. AMD has a different methodology because they don't support the same cpuid leaves as Intel. The most up to date info I could find about AMD (from 2013) is at http://developer.amd.com/resources/documentation-articles/articles-whitepapers/processor-and-core-enumeration-using-cpuid/

I dug up all this info while updating the Wikipedia page on CPUID today, by the way.

Kerchief answered 11/7, 2014 at 18:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.