implementaciones CPUID en C ++
Pregunta
Me gustaría saber si alguien de por aquí tiene algunos buenos ejemplos de una implementación en C ++ CPUID que se puede hacer referencia a cualquiera de los lenguajes .NET administrados.
Además, si este no fuera el caso, debería tener en cuenta ciertas diferencias de implementación entre X86 y X64?
Me gustaría utilizar CPUID para obtener información sobre la máquina de mi software se ejecuta en (crashreporting etc ...) y quiero mantener todo lo más ampliamente compatibles como sea posible.
razón primaria que pido es porque soy un novato total cuando se trata de escribir lo que probablemente será todas las instrucciones de la máquina aunque no tengo conocimientos básicos sobre registros de la CPU y así sucesivamente ...
Antes de empezar a contar la gente me para Google: He encontrado algunos ejemplos en línea, pero por lo general no estaban destinados a permitir la interacción de código administrado y ninguno de los ejemplos fueron dirigida tanto a X86 y X64. La mayoría de los ejemplos parecían ser X86 específica.
Solución
Acceso a la información CPUID prima es realmente muy fácil, aquí hay una clase de C ++ porque lo que funciona en Windows, Linux y OSX:
#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
Para usarlo sólo se crea una instancia de la clase, cargue la instrucción CPUID le interesa y examinar los registros. Por ejemplo:
#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;
}
Esta página de Wikipedia se explica cómo utilizar CPUID: http://en.wikipedia.org/wiki/CPUID
EDIT: #include <intrin.h>
añadido para Windows, por los comentarios
Otros consejos
este artículo de MSDN sobre __cpuid .
Hay una amplia muestra que compila con Visual Studio 2005 o mejor. Para Visual Studio 6, puede utilizar esto en vez del compilador __cpuid intrínseca:
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
}
}
Para Visual Studio 2005, puede utilizar esto en vez del compilador __cpuidex intrínseca:
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
}
}
Puede que no sea exactamente lo que está buscando, pero Intel tiene un buen artículo y código de ejemplo para enumerar Intel 64 bits arquitecturas de plataforma (procesador, memoria caché, etc.) que también parece cubrir los procesadores x86 de 32 bits.