この周りの誰かが、任意のマネージド.net言語から参照できるC++ CPUID実装の良い例を持っているかどうか知りたいです。
また、これが当てはまらない場合、X86とX64の間の特定の実装の違いに注意する必要がありますか?
CPUIDを使用して、ソフトウェアが実行されているマシンに関する情報(クラッシュレポートなど)を取得したいと思います。また、すべての互換性を可能な限り広くしたいと考えています。
私が尋ねる主な理由は、CPUレジスタなどに関する基本的な知識を持っているにもかかわらず、おそらくすべての機械命令になるものを書くことに関して、私はまったくの初心者だからです...
人々がGoogleに話し始める前に、オンラインでいくつかの例を見つけましたが、通常、それらはマネージコードからの対話を許可することを意図しておらず、X86とX64の両方を対象とした例はありませんでした。ほとんどの例はX86固有であるように見えました。
生の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
EDIT:コメントごとにWindows用の#include <intrin.h>
を追加しました。
この__cpuidに関するMSDNの記事 を参照してください。
Visual Studio 2005以降でコンパイルできる包括的なサンプルがあります。 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
}
}
探しているものとは正確には一致しない可能性がありますが、Intelには 良い記事とサンプルコード があり、Intel 64ビットプラットフォームアーキテクチャ(プロセッサ、キャッシュなど)を列挙できます。 。