Page 1 of 1

How to get number of threads?

Posted: Mon Feb 25, 2013 12:00 pm
by dancer
I want to get thread number. Which CPUID function gives me that number? I'm talking about Intel CPUs. I tried to get it by standard function EAX=1, reg EBX bits [23:16]. But some CPUs shows me that number of threads is 16. In Intel manual i found that this field is:


Bits 23-16: Maximum number of addressable IDs for logical processors
in this physical package*.

* The nearest power-of-2 integer that is not smaller than EBX[23:16]
is the number of unique initial APIC IDs reserved for addressing different
logical processors in a physical package. This field is only valid
if CPUID.1.EDX.HTT[bit 28]= 1.


So this is a not the number of threads? It is the number of addressable identyfiers for threads, right? So where i find this number?

Below are the results of my CPUID program.

---------------------------------------------------------------------
Vendor ID : GenuineIntel
Processor name : Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz

Processor type : 1

0 - N/A
1 - OEM
2 - OverDrive
3 - Dual

Stepping ID : 09
Model : 10
Family Code : 06
Extended Model : 03
Extended Family: 000

Brand Index : 00
Threads/CPU : 16 ;!!! this is what i'm talking about
Default APIC ID: 04
CLFLUSH size : 00064 bytes

Largest CPUID standard function: 13
Largest CPUID extended function: 08

EAX = 000306A9 ;regs after CPUID EAX = 1
EBX = 04100800
ECX = 7FBAE3FF
EDX = BFEBFBFF
----------------------------------------------------------------------
Vendor ID : GenuineIntel
Processor name : Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz

Processor type : 1

0 - N/A
1 - OEM
2 - OverDrive
3 - Dual

Stepping ID : 07
Model : 10
Family Code : 06
Extended Model : 02
Extended Family: 000

Brand Index : 00
Threads/CPU : 16 ;!!! this is what i'm talking about
Default APIC ID: 02
CLFLUSH size : 00064 bytes

Largest CPUID standard function: 13
Largest CPUID extended function: 08

EAX = 000206A7 ;regs after CPUID EAX = 1
EBX = 02100800
ECX = 1FBAE3BF
EDX = BFEBFBFF
-------------------------------------------------------------------------

thanks in advance

Re: How to get number of threads?

Posted: Mon Feb 25, 2013 12:20 pm
by Combuster
The correct place to find the list of all available execution units would be ACPI.

If you insist on sticking to CPUID, your processor might have info in EAX=0x0B, but it won't be telling the entire story.

Re: How to get number of threads?

Posted: Mon Feb 25, 2013 12:21 pm
by Brendan
Hi,
dancer wrote:Bits 23-16: Maximum number of addressable IDs for logical processors
in this physical package*.

* The nearest power-of-2 integer that is not smaller than EBX[23:16]
is the number of unique initial APIC IDs reserved for addressing different
logical processors in a physical package. This field is only valid
if CPUID.1.EDX.HTT[bit 28]= 1.


So this is a not the number of threads?
It is the total number of potential "threads" (logical CPUs). The actual number may be less than the total (e.g. because hyper-threading is disabled, or because core/s were disabled by Intel, or because the firmware found out that a logical CPU is faulty, etc).

The only way to determine the actual number of logical CPUs is to start all of the CPUs, and (using the CPU's local APIC ID) determine which logical CPUs belong to which physical package. This mostly means using CPUID to determine a set of shifts and masks for that CPU, then doing "package_ID = (local_APIC_ID >> package_shift) & package_mask;" and then maybe "table_of_CPUs_per_package[package_ID]++;".

For example:

Code: Select all

Threads/CPU    : 16			;!!! this is what i'm talking about
Default APIC ID: 04

package_shift = 4 (because 1 << 4 = 16)
package_ID = APIC_ID >> package_shift = 04 >> 4 = 0

Code: Select all

Threads/CPU    : 16			;!!! this is what i'm talking about
Default APIC ID: 02

package_shift = 4 (because 1 << 4 = 16)
package_ID = APIC_ID >> package_shift = 02 >> 4 = 0
This would mean that both CPUs are in the same package; and therefore you actually have 2 logical CPUs (out of 16 possible logical CPUs) in that physical package.

Note that Intel don't actually make a CPU with only 2 logical CPUs. Instead, they make an 8-core CPU with hyper-threading, then (for the cheaper CPUs) they disable hyper-threading and some/most of the cores afterwards and sell it as a "dual core without hyper-threading". This is called "product differentiation" (but Intel also do it because it means they can sell faulty CPUs - e.g. if 2 of the 8 cores don't work, then they can sell it as a quad-core or dual-core chip).


Cheers,

Brendan

Re: How to get number of threads?

Posted: Mon Feb 25, 2013 1:08 pm
by dancer
Things about you're write are too advanced to me. I have too many lack of knowledge.

Combuster, i dont know what is ACPI.
The only way to determine the actual number of logical CPUs is to start all of the CPUs, and (using the CPU's local APIC ID) determine which logical CPUs belong to which physical package. This mostly means using CPUID to determine a set of shifts and masks for that CPU, then doing "package_ID = (local_APIC_ID >> package_shift) & package_mask;" and then maybe "table_of_CPUs_per_package[package_ID]++;".
Brendan, how to start all CPUs?

I better know assembly than C. If you could use assembly.
Sorry for my english.

Re: How to get number of threads?

Posted: Mon Feb 25, 2013 1:40 pm
by Brendan
Hi,
dancer wrote:
The only way to determine the actual number of logical CPUs is to start all of the CPUs, and (using the CPU's local APIC ID) determine which logical CPUs belong to which physical package. This mostly means using CPUID to determine a set of shifts and masks for that CPU, then doing "package_ID = (local_APIC_ID >> package_shift) & package_mask;" and then maybe "table_of_CPUs_per_package[package_ID]++;".
Brendan, how to start all CPUs?
To start all the CPUs:
  • Try to get a list of the other CPU's APIC IDs from ACPI's "APIC/MADT" table
  • If that didn't work (e.g. computer is so old it doesn't support ACPI), try to get a list of the other CPU's APIC IDs from the MultiProcessor Specification tables
  • If that didn't work, it's a single-CPU computer
  • Otherwise; for each CPU listed in the "list of the other CPU's APIC IDs", you need to use the boot CPU's local APIC to send special IPIs (Inter-Processor Interrupts) to the other CPUs to wake them up. This sequence is known as the "INIT-SIPI-SIPI sequence", and is documented in Intel's manual and in Intel's MultiProcessor Specification
Once you've started all the CPUs, you can use CPUID (in each individual CPU) to determine which package and which core each logical CPU is in.

Note: I underlined terms that might be worth looking up in Intel's manual/s, in the OSdev wiki, and/or google. It's likely that you'll need to spend a few days reading stuff...


Cheers,

Brendan

Re: How to get number of threads?

Posted: Mon Feb 25, 2013 1:54 pm
by dancer
It's likely that you'll need to spend a few days reading stuff...I see,
Unfortunately right. Thanks for replies.