Jump to content
  • Advertisement
Sign in to follow this  
certaintragedy

Determining Processor Type/Brand at Runtime

This topic is 5059 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How does one determine the type or processor that a program is executing on at runtime (under windows and/or linux)? Specifically I want to know whether or not I'm running on an AMD or Intel processor. Thanks

Share this post


Link to post
Share on other sites
Advertisement
Well, I am bored, so here it goes:


#include <iostream>
#include <string>

using namespace std;

bool IsCPUIDSupported(void)
{
__try
{
__asm
{
mov eax, 0
CPUID
}
}
__except (1)
{
return false;
}

return true;
}

string GetCPUName(void)
{
char proc_name[49] = {0}; // name can be max 48 chars long

__asm
{
mov eax,0x080000002 // get first 16 chars
CPUID
mov DWORD PTR [proc_name + 0],eax
mov DWORD PTR [proc_name + 4],ebx
mov DWORD PTR [proc_name + 8],ecx
mov DWORD PTR [proc_name + 12],edx
mov eax,0x080000003 // get next 16 chars
CPUID
mov DWORD PTR [proc_name + 16],eax
mov DWORD PTR [proc_name + 20],ebx
mov DWORD PTR [proc_name + 24],ecx
mov DWORD PTR [proc_name + 28],edx
mov eax,0x080000004 // get last 16 chars
CPUID
mov DWORD PTR [proc_name + 32],eax
mov DWORD PTR [proc_name + 36],ebx
mov DWORD PTR [proc_name + 40],ecx
mov DWORD PTR [proc_name + 44],edx
}

return string(proc_name);
}

string GetCPUVendor(void)
{
char proc_vendor_id[13] = {0}; // vendor is always 12 chars

__asm
{
mov eax, 0
CPUID
mov DWORD PTR [proc_vendor_id + 0],ebx
mov DWORD PTR [proc_vendor_id + 4],edx
mov DWORD PTR [proc_vendor_id + 8],ecx
}

return string(proc_vendor_id);
}

int main(void)
{
if (IsCPUIDSupported())
{
cout << "CPU Vendor ID: " << GetCPUVendor() << endl;
cout << "CPU Name: " << GetCPUName() << endl;
}
else
{
cout << "CPUID is not supported on your machine!" << endl;
}

getchar();

return 0;
}




There are 3 function - one to test for cpuid support (it should be supported on anything newer than pentium), one to get vendor ID string and last one gets processor name.
HTH

Share this post


Link to post
Share on other sites
Under Windows, you can call GetSystemInfo() and IsProcessorFeaturePresent() to get some data on your CPU. The latter is pretty cool, since you can test for SSE, 3DNOW, and so on, then store these in a global (or Singleton) data store and switch code paths later to use the most efficient algorithms depending on the hardware available.

Share this post


Link to post
Share on other sites
I do it with this:


struct
{
char vendor [13];
char name [64];
char stepping;
char model;
char family;
char type;
char extended_model;
char extended_family;

bool FPU;
bool VME;
bool DE;
bool PSE;
bool TSC;
bool MSR;
bool PAE;
bool MCE;
bool CX8;
bool APIC;
bool reserved0;
bool SEP;
bool MTRR;
bool PGE;
bool MCA;
bool CMOV;
bool PAT;
bool PSE36;
bool PSN;
bool CLFSH;
bool reserved1;
bool DS;
bool ACPI;
bool MMX;
bool FXSR;
bool SSE;
bool SSE2;
bool SS;
bool HTT;
bool TM;
bool reserved2;
bool SBF;
} CPU;

void check_processor_features()
{
struct
{
int max_eax;
char vendorstring[4*4];
int signature;
int feature_flags[3];
} CPUID;
CPUID.vendorstring[0] = 0;

#ifdef _WIN32
int &max_eax = CPUID.max_eax;
__asm
{
pushad ; save all general purpose registers into the stack
pushfd ; save processor state flags into the stack

mov esi, max_eax ; copy &max_eax to %esi

xor eax, eax ; reset %eax
cpuid ; call cpuid
mov [esi ], eax ; max_eax = %eax
mov [esi+ 4], ebx ; vendorstring[0-3] = %ebx = 0x47656e75 ("Genu")
mov [esi+ 8], edx ; vendorstring[4-7] = %edx = 0x696e654e ("ineI")
mov [esi+12], ecx ; vendorstring[8-b] = %ecx = 0x6e74656c ("ntel")
xor eax, eax ; reset %eax
mov [esi+16], eax ; vendorstring[c-f] = 0x00000000 ("")
inc eax ; ++%eax
cpuid ; call cpuid
mov [esi+20], eax ; signature = %eax
mov [esi+24], ebx ; feature_flags[0] = %ebx
mov [esi+28], ecx ; feature_flags[1] = %ecx
mov [esi+32], edx ; feature_flags[2] = %edx

popfd ; restore processor state flags form the stack
popad ; restore original register values from the stack
}
#else
asm volatile
(
"pusha /* save all general purpose registers into the stack */\n\t"
"pushf /* save processor state flags into the stack */\n\t"
"\n\t"
"lea %0, %%esi /* copy &max_eax to %%esi */\n\t"
"\n\t"
"xor %%eax, %%eax /* reset %%eax */\n\t"
"cpuid /* call cpuid */\n\t"
"mov %%eax, (%%esi) /* max_eax = %%eax */\n\t"
"mov %%ebx, 4(%%esi) /* vendorstring[0-3] = %%ebx = 0x41757468 (\"Auth\") */\n\t"
"mov %%edx, 8(%%esi) /* vendorstring[4-7] = %%edx = 0x656e7469 (\"enti\") */\n\t"
"mov %%ecx, 12(%%esi) /* vendorstring[8-b] = %%ecx = 0x63414d44 (\"cAMD\") */\n\t"
"xor %%eax, %%eax /* reset %%eax */\n\t"
"mov %%eax, 16(%%esi) /* vendorstring[c-f] = 0x00000000 (\"\") */\n\t"
"inc %%eax /* ++%%eax */\n\t"
"cpuid /* call cpuid */\n\t"
"mov %%eax, 20(%%esi) /* signature = %%eax */\n\t"
"mov %%ebx, 24(%%esi) /* feature_flags[0] = %%ebx */\n\t"
"mov %%ecx, 28(%%esi) /* feature_flags[1] = %%ecx */\n\t"
"mov %%edx, 32(%%esi) /* feature_flags[2] = %%edx */\n\t"
"\n\t"
"popf /* restore processor state flags form the stack */\n\t"
"popa /* restore original register values from the stack */\n\t"
:
: "m"(CPUID.max_eax)
);
#endif

strcpy(CPU.vendor, CPUID.vendorstring);
CPU.extended_family = (CPUID.signature>>20) & 0xff;
CPU.extended_model = (CPUID.signature>>16) & 0x0f;
CPU.type = (CPUID.signature>>12) & 0x03;
CPU.family = (CPUID.signature>> 8) & 0x0f;
CPU.model = (CPUID.signature>> 4) & 0x0f;
CPU.stepping = (CPUID.signature>> 0) & 0x0f;

...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!