cpuidでAVX2に対応しているか調べる
intelの以下のページに方法とコードが書いてあります.
AVX2等は以下のCPUIDで調べることができます.
CPUID.(EAX=01H, ECX=0H):ECX.FMA[bit 12]==1 CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]==1 CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]==1 CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]==1 CPUID.(EAX=80000001H):ECX.LZCNT[bit 5]==1 CPUID.(EAX=01H, ECX=0H):ECX.MOVBE[bit 22]==1
以下,検証用コード (とりあえず自分の環境で動けば良かったのでかなり適当です)
#include <stdio.h> #include <string.h> struct abcd{ unsigned int a,b,c,d; }; void cpuid(struct abcd* r, unsigned int eax, unsigned int ecx){ __asm__ volatile ("cpuid" :"=a"(r->a), "=b"(r->b), "=c"(r->c), "=d"(r->d) : "a"(eax), "c"(ecx)); } int main(){ struct abcd r; char buf[48]; // GenuinIntel cpuid(&r, 0x0, 0x0); printf("0x%x\n", r.a); memcpy(buf, &r.b, 4); memcpy(buf+4, &r.d, 4); memcpy(buf+8, &r.c, 4); buf[12] = '\0'; printf("%s\n", buf); // Processor Name, Freq cpuid(&r, 0x80000002, 0x0); memcpy(buf, &r, 16); cpuid(&r, 0x80000003, 0x0); memcpy(buf+16, &r, 16); cpuid(&r, 0x80000004, 0x0); memcpy(buf+32, &r, 16); printf("%s\n", buf); // SIMD // https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family cpuid(&r, 0x1, 0x0); printf("MMX: %s\n", r.d & 1 << 23 ? "OK" : "NG"); printf("SSE: %s\n", r.d & 1 << 25 ? "OK" : "NG"); printf("AVX: %s\n", r.c & 1 << 28 ? "OK" : "NG"); printf("FMA: %s\n", r.c & 1 << 12 ? "OK" : "NG"); cpuid(&r, 0x7, 0x0); printf("AVX2: %s\n", r.b & 1 << 5 ? "OK" : "NG"); return 0; }
実行結果
% gcc-6 cpuid.c % ./a.out 0x16 GenuineIntel Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz MMX: OK SSE: OK AVX: OK FMA: OK AVX2: OK