Pergunta

Gostaria de saber se alguém aqui tem alguns bons exemplos de uma aplicação C ++ CPUID que pode ser referenciada a partir de qualquer das linguagens .NET gerenciados.

Além disso, no caso de não ser o caso, eu deveria estar ciente de algumas diferenças de implementação entre X86 e X64?

Eu gostaria de usar CPUID para obter informações sobre a máquina o meu software está em execução no (crashreporting etc ...) e eu quero manter tudo o mais amplamente compatível possível.

Principal razão que eu peço é porque eu sou um noob total quando se trata de escrever o que será, provavelmente, todas as instruções de máquina que eu tenha conhecimento básico sobre registros de CPU e assim por diante ...

Antes das pessoas começam a dizer-me para o Google: Eu encontrei alguns exemplos on-line, mas normalmente eles não foram feitos para permitir a interação do código gerenciado e nenhum dos exemplos visavam tanto X86 e X64. A maioria dos exemplos parecia ser X86 específico.

Foi útil?

Solução

O acesso à informação CPUID cru é realmente muito fácil, aqui é uma classe C ++ para o que funciona em Windows, Linux e 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 usá-lo apenas criar uma instância da classe, coloque a instrução CPUID você está interessado em e examinar os registros. Por exemplo:

#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 Wikipedia diz-lhe como usar CPUID: http://en.wikipedia.org/wiki/CPUID

EDIT:. #include <intrin.h> Adicionado para Windows, por comentários

Outras dicas

este artigo MSDN sobre __cpuid .

Há uma amostra abrangente que compila com o Visual Studio 2005 ou melhor. Para 6 Visual Studio, você pode usar isso em vez do instrinsic compilador __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, você pode usar isso em vez do __cpuidex intrínseca do compilador:

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  
  }
}

Pode não ser exatamente o que você está procurando, mas a Intel tem uma bom artigo e código de exemplo para enumerar Intel 64 arquitecturas plataforma bits (processador, memória cache, etc), que também parece abranger processadores x86 de 32 bits.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top