Skip to main content
GameDev.net gamedev.net
🔒 Locked

Determining Processor Type/Brand at Runtime

Started by certaintragedy Jan 8, 2005 at 4:11 PM 4 replies 2.5k views
Original Post
certaintragedy
certaintragedy
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
b2b3
b2b3
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
StaticEngine
StaticEngine
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.
666_1337
666_1337
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;       ...
our new version has many new and good features. sadly, the good nes are not new and the new nes are not good oo

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.