Implementacje CPUID w C++
Chciałbym się dowiedzieć, czy ktoś tutaj ma jakieś dobre przykłady implementacji C++ CPUID, do której można się odwoływać z dowolnego zarządzanego języka. NET.
Ponadto, czy nie powinno tak być, Czy powinienem być świadomy pewnych różnic w implementacji między X86 i X64?
Chciałbym użyć CPUID, aby uzyskać informacje o maszynie, na której działa moje oprogramowanie (crashreporting itp...) i chcę, aby wszystko było jak najbardziej zgodne.
Główny powód I pytanie jest, ponieważ jestem totalnym noobem, jeśli chodzi o pisanie tego, co prawdopodobnie będzie wszystkimi instrukcjami maszynowymi, chociaż mam podstawową wiedzę na temat rejestrów CPU i tak dalej...
Zanim ludzie zaczną mi mówić do Google: znalazłem kilka przykładów online, ale zazwyczaj nie miały one pozwolić na interakcję z zarządzanym kodem i żaden z przykładów nie był skierowany zarówno do X86, jak i X64. Większość przykładów wydaje się być specyficzna dla X86.
3 answers
Dostęp do surowych informacji o CPUID jest w rzeczywistości bardzo łatwy, oto Klasa C++ dla tego, co działa w systemach Windows, Linux i 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
Aby użyć go po prostu utworzyć instancję instancji klasy, załaduj instrukcję CPUID, którą jesteś zainteresowany i sprawdź rejestry. Na przykład:
#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;
}
Ta strona Wikipedii mówi, jak używać CPUID: http://en.wikipedia.org/wiki/CPUID
EDIT: Added #include <intrin.h>
for Windows, per comments.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 21:50:53
Zobacz Ten artykuł MSDN o __cpuid .
Istnieje obszerna próbka, która kompiluje się z Visual Studio 2005 lub lepszym. W przypadku Visual Studio 6 możesz użyć tego zamiast kompilatora 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
}
}
W Visual Studio 2005 możesz użyć tego zamiast kompilatora 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 12:52:09
Może nie jest dokładnie tym, czego szukasz, ale Intel ma Dobry artykuł i przykładowy kod do wyliczenia 64-bitowych architektur platformy Intel (Procesor, Pamięć podręczna itp.), który również wydaje się obejmować 32-bitowe procesory x86.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 14:14:34