30

この辺りの誰かが、マネージド.net言語のいずれかから参照できるC++CPUID実装の良い例をいくつか持っているかどうか知りたいです。

また、これが当てはまらない場合は、X86とX64の特定の実装の違いに注意する必要がありますか?

CPUIDを使用して、ソフトウェアが実行されているマシンに関する情報(crashreportingなど)を取得したいと思います。また、すべてを可能な限り広く互換性を保ちたいと考えています。

私が尋ねる主な理由は、CPUレジスタなどの基本的な知識はありますが、おそらくすべてのマシン命令になるものを書くことに関しては、私はまったくの初心者だからです...

人々が私にGoogleに話し始める前に:私はいくつかの例をオンラインで見つけましたが、通常、それらはマネージコードからの対話を許可することを意図しておらず、どの例もX86とX64の両方を対象としていませんでした。ほとんどの例はX86固有のようです。

4

3 に答える 3

51

生の CPUID 情報へのアクセスは実際には非常に簡単です。Windows、Linux、および OSX で動作する C++ クラスを次に示します。

#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

それを使用するには、クラスのインスタンスをインスタンス化し、関心のある CPUID 命令をロードして、レジスタを調べます。例えば:

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

このウィキペディアのページでは、CPUID の使用方法について説明しています: http://en.wikipedia.org/wiki/CPUID

編集:#include <intrin.h>コメントごとに、Windows 用に追加されました。

于 2011-01-28T01:23:32.090 に答える
8

__cpuidに関するこのMSDNの記事を参照してください。

VisualStudio2005以降でコンパイルされる包括的なサンプルがあります。Visual Studio 6の場合、コンパイラーの本能的な__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  
  }
}

Visual Studio 2005の場合、コンパイラーの本能的な__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  
  }
}
于 2012-01-20T13:05:33.813 に答える
2

まさにあなたが探しているものではないかもしれませんが、Intel には、32 ビット x86 プロセッサもカバーしているように見える Intel 64 ビット プラットフォーム アーキテクチャ (プロセッサ、キャッシュなど) を列挙するための優れた記事とサンプル コードがあります。

于 2009-11-03T09:18:10.620 に答える