How can I detect which CPU is being used at runtime ? The c++ code needs to differentiate between AMD / Intel architectures ? Using gcc 4.2.
6 Answers
The cpuid
instruction, used with EAX=0
will return a 12-character vendor string in EBX
, EDX
, ECX
, in that order.
For Intel, this string is "GenuineIntel". For AMD, it's "AuthenticAMD". Other companies that have created x86 chips have their own strings.The Wikipedia page for cpuid
has many (all?) of the strings listed, as well as an example ASM listing for retrieving the details.
You really only need to check if ECX matches the last four characters. You can't use the first four, because some Transmeta CPUs also start with "Genuine"
- For Intel, this is
0x6c65746e
- For AMD, this is
0x444d4163
If you convert each byte in those to a character, they'll appear to be backwards. This is just a result of the little endian design of x86. If you copied the register to memory and looked at it as a string, it would work just fine.
Example Code:
bool IsIntel() // returns true on an Intel processor, false on anything else
{
int id_str; // The first four characters of the vendor ID string
__asm__ ("cpuid":\ // run the cpuid instruction with...
"=c" (id_str) : // id_str set to the value of EBX after cpuid runs...
"a" (0) : // and EAX set to 0 to run the proper cpuid function.
"eax", "ebx", "edx"); // cpuid clobbers EAX, ECX, and EDX, in addition to EBX.
if(id_str==0x6c65746e) // letn. little endian clobbering of GenuineI[ntel]
return true;
else
return false;
}
EDIT: One other thing - this can easily be changed into an IsAMD
function, IsVIA
function, IsTransmeta
function, etc. just by changing the magic number in the if
.

- 1,819
- 15
- 21
-
You could even make a function `int Last4()` that returns the last four characters as an int using the inline assembly, and then make `bool IsIntel() { return Last4() == 0x6c65746e; }` and `bool IsAMD() { return Last4() == 0x444d4163; }` quite easily. It also avoids code duplication and reduces the overall amount of inline assembly required. – Chris Lutz Sep 02 '09 at 01:57
If you're on Linux (or on Windows running under Cygwin), you can figure that out by reading the special file /proc/cpuinfo
and looking for the line beginning with vendor_id
. If the string is GenuineIntel
, you're running on an Intel chip. If you get AuthenticAMD
, you're running on an AMD chip.
void get_vendor_id(char *vendor_id) // must be at least 13 bytes
{
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
if(cpuinfo == NULL)
; // handle error
char line[256];
while(fgets(line, 256, cpuinfo))
{
if(strncmp(line, "vendor_id", 9) == 0)
{
char *colon = strchr(line, ':');
if(colon == NULL || colon[1] == 0)
; // handle error
strncpy(vendor_id, 12, colon + 2);
fclose(cpuinfo);
return;
}
}
// if we got here, handle error
fclose(cpuinfo);
}
If you know you're running on an x86 architecture, a less portable method would be to use the CPUID instruction:
void get_vendor_id(char *vendor_id) // must be at least 13 bytes
{
// GCC inline assembler
__asm__ __volatile__
("movl $0, %%eax\n\t"
"cpuid\n\t"
"movl %%ebx, %0\n\t"
"movl %%edx, %1\n\t"
"movl %%ecx, %2\n\t"
: "=m"(vendor_id), "=m"(vendor_id + 4), "=m"(vendor_id + 8) // outputs
: // no inputs
: "%eax", "%ebx", "%edx", "%ecx", "memory"); // clobbered registers
vendor_id[12] = 0;
}
int main(void)
{
char vendor_id[13];
get_vendor_id(vendor_id);
if(strcmp(vendor_id, "GenuineIntel") == 0)
; // it's Intel
else if(strcmp(vendor_id, "AuthenticAMD") == 0)
; // it's AMD
else
; // other
return 0;
}

- 390,455
- 97
- 512
- 589
-
I am quite sure it will be x86 architecture. Just need to differentiate between AMD and Intel. Although I am using gcc, dont think have access to /proc/cpuinfo. – vivekian2 Jan 21 '09 at 18:16
-
/proc/cpuinfo is world readable, so why do you think you can't access it? – phihag Jan 21 '09 at 18:22
-
The program is to run on DOS using DJGPP. So no access to /proc/cpuinfo – vivekian2 Jan 21 '09 at 18:38
-
This is the right way to do it if you want failover code when dealing with other brands - if you know your code will only ever run on AMD and Intel processors, I think mine is a bit clearer. – Branan Jan 21 '09 at 18:46
-
Reading /proc/cpuinfo feels like heavy artillery. I mean, it's like, a couple of lines of ASM code really, what's the point of reading /proc/cpuinfo to do that? – Tamas Czinege Jan 21 '09 at 18:47
-
here the cpudetection code used by mplayer: http://svn.mplayerhq.hu/mplayer/trunk/cpudetect.c?view=markup also look into cpudetect.h that has defines used. – Johannes Schaub - litb Jan 21 '09 at 18:51
-
@DrJokepu: readability/portability issues - not eveyrone's particularly brave to trek into asm territory, and maybe there's a need to port it to other arch. – Calyth Jan 22 '09 at 00:31
-
If you're running DOS, you're likely talking embedded. How would you not know? Your PCB design will spec Intel or AMD, or possibly another vendor. – MSalters Jan 22 '09 at 13:37
On Windows, you can use the GetNativeSystemInfo function
On Linux, try sysinfo

- 30,111
- 9
- 76
- 83
You probably should not check at all. Instead, check whether the CPU supports the features you need, e.g. SSE3. The differences between two Intel chips might be greater than between AMD and Intel chips.

- 173,980
- 10
- 155
- 350
I have posted a small project: http://sourceforge.net/projects/cpp-cpu-monitor/ which uses the libgtop library and exposes data through UDP. You can modify it to suit your needs. GPL open-source. Please ask if you have any questions regarding it.

- 1,278
- 1
- 8
- 17
You have to define it in your Makefile arch=uname -p 2>&1
, then use #ifdef i386 some #endif for diferent architectures.

- 604
- 4
- 12
-
1This detects what machine it was _compiled_ on, not what machine it's _running_ on. – Adam Rosenfield Jan 21 '09 at 18:41
-