EDIT: Это больше не на 100% правильное из-за продолжающегося befuddlement Intel.
Как я понимаю, вопрос заключается в том, что вы спрашиваете, как определить количество ядер процессора и потоков процессоров, которое отличается от определения количества логических и физических ядер в системе. Процессорные ядра часто не считаются физическими ядрами ОС, если у них нет собственного пакета или нет. Таким образом, ОС сообщит, что Core 2 Duo, например, имеет 1 физический и 2 логических процессора, а Intel P4 с гиперпотоками будет сообщаться точно так же, хотя 2 гиперпотока против 2 ядер процессора - это очень другой предмет выступление.
Я боролся с этим, пока не нашел решение ниже, которое, я считаю, работает как для процессоров AMD, так и для процессоров Intel. Насколько я знаю, и я могу ошибаться, AMD еще не имеет потоков ЦП, но они предоставили возможность обнаружить их, которые, как я полагаю, будут работать на будущих процессорах AMD, которые могут иметь потоки ЦП.
Короче вот шаги, с помощью инструкции CPUID:
- Detect поставщика CPU с помощью функции CPUID 0
- Проверить HTT укусил 28 в процессоре имеется EDX из функции CPUID 1
- Получить логическое основной отсчет от EBX [23:16] от функции CPUID 1
- Получить фактическое ядро без резьбы CPU рассчитывать
- Если поставщик == «GenuineIn тел»это 1 плюс EAX [31:26] из функции CPUID 4
- Если поставщик == 'AuthenticAMD' это 1 плюс ECX [7: 0] из функции CPUID 0x80000008
Звуки трудный, но вот, надеюсь, программа не зависит от платформы C++, которая делает трюк:
#include <iostream>
#include <string>
using namespace std;
void cpuID(unsigned i, unsigned regs[4]) {
#ifdef _WIN32
__cpuid((int *)regs, (int)i);
#else
asm volatile
("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
: "a" (i), "c" (0));
// ECX is set to zero for CPUID function 4
#endif
}
int main(int argc, char *argv[]) {
unsigned regs[4];
// Get vendor
char vendor[12];
cpuID(0, regs);
((unsigned *)vendor)[0] = regs[1]; // EBX
((unsigned *)vendor)[1] = regs[3]; // EDX
((unsigned *)vendor)[2] = regs[2]; // ECX
string cpuVendor = string(vendor, 12);
// Get CPU features
cpuID(1, regs);
unsigned cpuFeatures = regs[3]; // EDX
// Logical core count per CPU
cpuID(1, regs);
unsigned logical = (regs[1] >> 16) & 0xff; // EBX[23:16]
cout << " logical cpus: " << logical << endl;
unsigned cores = logical;
if (cpuVendor == "GenuineIntel") {
// Get DCP cache info
cpuID(4, regs);
cores = ((regs[0] >> 26) & 0x3f) + 1; // EAX[31:26] + 1
} else if (cpuVendor == "AuthenticAMD") {
// Get NC: Number of CPU cores - 1
cpuID(0x80000008, regs);
cores = ((unsigned)(regs[2] & 0xff)) + 1; // ECX[7:0] + 1
}
cout << " cpu cores: " << cores << endl;
// Detect hyper-threads
bool hyperThreads = cpuFeatures & (1 << 28) && cores < logical;
cout << "hyper-threads: " << (hyperThreads ? "true" : "false") << endl;
return 0;
}
Я на самом деле не проверял это на Windows, или OSX, но пока он должен работать как инструкция CPUID действует на i686 машинах. Очевидно, что это не будет работать для PowerPC, но тогда у них также нет гиперпотоков.
Вот вывод на нескольких разных машинах Intel:
Intel (R) ядро (TM) 2 Duo CPU T7500 @ 2.20GHz:
logical cpus: 2
cpu cores: 2
hyper-threads: false
Intel (R) ядро (TM) 2 Quad CPU Q8400 @ 2,66:
logical cpus: 4
cpu cores: 4
hyper-threads: false
Intel (R) Xeon (R) CPU E5520 @ 2.27GHz (ж/x2 физических пакетов CPU):
logical cpus: 16
cpu cores: 8
hyper-threads: true
Intel (R) Pentium (R) 4 CPU 3,00 ГГц:
logical cpus: 2
cpu cores: 1
hyper-threads: true
Проверьте это - http://stackoverflow.com/questions/150355/programmatically-find-the-number-of-cores-on-a-machine – Secko
Разве вы не задали один и тот же вопрос пару дней назад ? http://stackoverflow.com/questions/2904283/c-c-assembly-programatically-detect-if-hyper-threading-is-active-on-windows-ma –
Вы отказались от этого вопроса? – jcoffland