Implementaciones de CPUID en C++
Me gustaría saber si alguien por aquí tiene algunos buenos ejemplos de una implementación de CPUID de C++ a la que se pueda hacer referencia desde cualquiera de los lenguajes.net gestionados.
Además, si este no es el caso, ¿debo ser consciente de ciertas diferencias de implementación entre X86 y X64?
Me gustaría usar CPUID para obtener información sobre la máquina en la que se está ejecutando mi software (crashreporting, etc.)...) y quiero mantener todo lo más ampliamente compatible posible.
Razón principal I preguntar es porque soy un novato total cuando se trata de escribir lo que probablemente serán todas las instrucciones de la máquina, aunque tengo conocimientos básicos sobre registros de CPU y así sucesivamente...
Antes de que la gente comience a decirme a Google: Encontré algunos ejemplos en línea, pero generalmente no estaban destinados a permitir la interacción desde código administrado y ninguno de los ejemplos estaban dirigidos tanto a X86 como a X64. La mayoría de los ejemplos parecían ser específicos de X86.
3 answers
Acceder a la información de CPUID sin procesar es realmente muy fácil, aquí hay una clase de C++ para la 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 simplemente instanciar una instancia de la clase, cargue la instrucción CPUID que le interesa y examine 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 le dice cómo usar CPUID: http://en.wikipedia.org/wiki/CPUID
EDITAR: Añadido #include <intrin.h>
para Windows, por comentarios.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-27 21:50:53
Ver este artículo de MSDN sobre __cpuid.
Hay una muestra completa que compila con Visual Studio 2005 o superior. Para Visual Studio 6, puede usar esto en lugar del compilador 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
}
}
Para Visual Studio 2005, puede usar esto en lugar del compilador 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
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-09 12:52:09
Podría no ser exactamente lo que está buscando, pero Intel tiene un buen artículo y código de ejemplo para enumerar arquitecturas de plataformas Intel de 64 bits (procesador, caché, etc.) que también parece cubrir procesadores x86 de 32 bits.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-12 14:14:34