implémentations CPUID en C ++
Question
Je voudrais savoir si quelqu'un ici a quelques bons exemples d'implémentation C ++ CPUID qui peut être référencé à partir de l'une des langues .net gérés.
En outre, si cela ne pas être le cas, dois-je être au courant de certaines différences de mise en œuvre entre X86 et X64?
Je voudrais utiliser CPUID pour obtenir des informations sur la machine mon logiciel fonctionne sur (crashreporting etc ...) et je veux garder tout aussi largement compatible que possible.
Raison principale Je demande parce que je suis un noob totale en ce qui concerne l'écriture ce qui sera probablement toutes les instructions de la machine que j'ai des connaissances de base sur les registres CPU et ainsi de suite ...
Avant que les gens commencent à me dire à Google: J'ai trouvé quelques exemples en ligne, mais le plus souvent ils ne sont pas destinés à permettre une interaction du code managé et aucun des exemples ont été visant à la fois et X64 X86. La plupart des exemples semblaient X86 spécifiques.
La solution
Accès aux informations CPUID premières est en fait très simple, voici une classe C ++ ce qui fonctionne sous Windows, Linux et Mac OS X:
#ifndef CPUID_H
#define CPUID_H
#ifdef _WIN32
#include <limits.h>
#include <intrin.h>
typedef unsigned __int32 uint32_t;
#else
#include <stdint.h>
#endif
class CPUID {
uint32_t regs[4];
public:
explicit CPUID(unsigned i) {
#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
}
const uint32_t &EAX() const {return regs[0];}
const uint32_t &EBX() const {return regs[1];}
const uint32_t &ECX() const {return regs[2];}
const uint32_t &EDX() const {return regs[3];}
};
#endif // CPUID_H
Pour utiliser juste instancier une instance de la classe, charger l'instruction CPUID vous intéresse et examiner les registres. Par exemple:
#include "CPUID.h"
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
CPUID cpuID(0); // Get CPU vendor
string vendor;
vendor += string((const char *)&cpuID.EBX(), 4);
vendor += string((const char *)&cpuID.EDX(), 4);
vendor += string((const char *)&cpuID.ECX(), 4);
cout << "CPU vendor = " << vendor << endl;
return 0;
}
Cette page Wikipédia indique comment utiliser CPUID: http://en.wikipedia.org/wiki/CPUID
EDIT: Ajout #include <intrin.h>
pour Windows, par commentaires
Autres conseils
Voir cet article MSDN sur les __cpuid.
Il y a un échantillon complet qui compile avec Visual Studio 2005 ou mieux. Pour Visual Studio 6, vous pouvez utiliser cette place du compilateur instrinsic __cpuid:
void __cpuid(int CPUInfo[4], int InfoType)
{
__asm
{
mov esi, CPUInfo
mov eax, InfoType
xor ecx, ecx
cpuid
mov dword ptr [esi + 0], eax
mov dword ptr [esi + 4], ebx
mov dword ptr [esi + 8], ecx
mov dword ptr [esi + 12], edx
}
}
Pour Visual Studio 2005, vous pouvez l'utiliser au lieu du compilateur instrinsic __cpuidex:
void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue)
{
__asm
{
mov esi, CPUInfo
mov eax, InfoType
mov ecx, ECXValue
cpuid
mov dword ptr [esi + 0], eax
mov dword ptr [esi + 4], ebx
mov dword ptr [esi + 8], ecx
mov dword ptr [esi + 12], edx
}
}
Peut-être pas exactement ce que vous cherchez, mais Intel avez bon article et exemple de code pour les architectures de plate-forme énumération de bits Intel 64 (processeur, mémoire cache, etc.) qui semble aussi couvrir 32 bits des processeurs x86.