EDIT : Ce n'est plus correct à 100% en raison de l'incompréhension permanente d'Intel.
Si je comprends bien votre question, vous demandez comment détecter le nombre de cœurs de processeur par rapport aux threads de processeur, ce qui est différent de la détection du nombre de cœurs logiques et physiques dans un système. Les cœurs du processeur ne sont souvent pas considérés comme des cœurs physiques par le système d'exploitation, à moins qu'ils n'aient leur propre paquet ou matrice. Ainsi, un système d'exploitation indiquera qu'un Core 2 Duo, par exemple, possède 1 processeur physique et 2 processeurs logiques, et un Intel P4 avec hyper-threads sera indiqué exactement de la même manière, même si 2 hyper-threads et 2 cœurs de processeur sont très différents en termes de performances.
Je me suis débattu avec ce problème jusqu'à ce que je trouve la solution ci-dessous, qui, je pense, fonctionne pour les processeurs AMD et Intel. Pour autant que je sache, et je peux me tromper, AMD n'a pas encore de threads CPU mais ils ont fourni un moyen de les détecter qui, je suppose, fonctionnera sur les futurs processeurs AMD qui pourraient avoir des threads CPU.
En résumé, voici les étapes à suivre pour utiliser l'instruction CPUID :
- Détecter le fournisseur du CPU en utilisant la fonction CPUID 0
- Vérification du bit HTT 28 dans les caractéristiques du CPU EDX de la fonction CPUID 1
- Obtenez le nombre de noyaux logiques à partir de EBX[23:16] de la fonction CPUID 1.
- Obtenir le nombre réel de cœurs de processeurs non-threadés
- Si le vendeur == 'GenuineIntel', c'est 1 plus EAX[31:26] de la fonction 4 du CPUID.
- Si le vendeur == 'AuthenticAMD', c'est 1 plus ECX[7:0] de la fonction CPUID 0x80000008.
Cela semble difficile, mais voici un programme C++, indépendant de la plate-forme, qui fait l'affaire :
#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;
}
Je n'ai pas encore testé cela sous Windows ou OSX mais cela devrait fonctionner puisque l'instruction CPUID est valide sur les machines i686. Évidemment, cela ne fonctionnera pas pour les PowerPC mais ils n'ont pas d'hyper-threads non plus.
Voici le résultat sur quelques machines Intel différentes :
Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz :
logical cpus: 2
cpu cores: 2
hyper-threads: false
Intel(R) Core(TM)2 Quad CPU Q8400 @ 2.66GHz :
logical cpus: 4
cpu cores: 4
hyper-threads: false
Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (avec x2 paquets de CPU physiques) :
logical cpus: 16
cpu cores: 8
hyper-threads: true
Intel(R) Pentium(R) 4 CPU 3.00GHz :
logical cpus: 2
cpu cores: 1
hyper-threads: true
1 votes
Regarde ça - stackoverflow.com/questions/150355/
1 votes
N'avez-vous pas posé la même question il y a deux jours ? stackoverflow.com/questions/2904283/
0 votes
Avez-vous abandonné cette question ?
0 votes
Avez-vous réussi à résoudre ce problème ? Avez-vous encore besoin d'aide à ce sujet ?
0 votes
Nous travaillons actuellement sur une solution multiplateforme pour accéder aux informations sur le matériel et les systèmes : github.com/lfreist/hwinfo