How to detect what CPU is being used during runtime?

安稳与你 提交于 2019-12-22 08:52:39

问题


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.


回答1:


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;
}



回答2:


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.




回答3:


On Windows, you can use the GetNativeSystemInfo function

On Linux, try sysinfo




回答4:


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.




回答5:


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




回答6:


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.



来源:https://stackoverflow.com/questions/466377/how-to-detect-what-cpu-is-being-used-during-runtime

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!