Skip to content

Instantly share code, notes, and snippets.

@t-mat
Last active March 28, 2024 12:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t-mat/3769328 to your computer and use it in GitHub Desktop.
Save t-mat/3769328 to your computer and use it in GitHub Desktop.
CPUIDを使ってCPUの情報を取得する
  • Pentium 以降の世代の CPU なら問題なく実行できる
  • VC++ (2005 以降?) なら <intrin.h>#include して、__cpuid() および __cpuidex() を使用する
  • gcc なら <cpuid.h>#include して、__get_cpuid(), __cpuid_count() を使用する
  • RDRAND を使ってみたかったのだけど、うちのは対応していなかった!
// CPUID example
//
// see below for details:
//
// Intel Processor Identification and the CPUID Instruction
// https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-manual.html
//
// AMD : CPUID Specification
// http://support.amd.com/us/Embedded_TechDocs/25481.pdf
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#if defined(_MSC_VER)
#include <intrin.h>
static void get_cpuid(void* p, int i) {
__cpuid((int*)p, i);
}
static void get_cpuidex(void* p, int i, int c) {
__cpuidex((int*)p, i, c);
}
#elif defined(__GNUC__)
#include <cpuid.h>
static void get_cpuid(void* p, int i) {
int* a = (int*) p;
__cpuid(i, a[0], a[1], a[2], a[3]);
}
static void get_cpuidex(void* p, int i, int c) {
int* a = (int*) p;
__cpuid_count(i, c, a[0], a[1], a[2], a[3]);
}
#endif
struct CpuInfo {
uint32_t eax, ebx, ecx, edx; // Do not change member order.
CpuInfo(int infoType) {
get_cpuid(&eax, infoType);
}
CpuInfo(int infoType, uint32_t ecxValue) {
get_cpuidex(&eax, infoType, ecxValue);
}
};
static_assert(offsetof(CpuInfo, eax) == 0, "CpuInfo::eax");
static_assert(offsetof(CpuInfo, ebx) == 4, "CpuInfo::ebx");
static_assert(offsetof(CpuInfo, ecx) == 8, "CpuInfo::ecx");
static_assert(offsetof(CpuInfo, edx) == 12, "CpuInfo::edx");
int main() {
{
char vendor[12+1] = { 0 };
CpuInfo f0(0);
* (uint32_t*) &vendor[4*0] = f0.ebx;
* (uint32_t*) &vendor[4*1] = f0.edx;
* (uint32_t*) &vendor[4*2] = f0.ecx;
vendor[sizeof(vendor)-1] = 0;
printf("Vendor : [%s]\n", vendor);
}
{
char brand[16*3+1] = { 0 };
for(int i = 0; i < 3; ++i) {
CpuInfo e(i + 0x80000002);
* (uint32_t*) &brand[16*i + 4*0] = e.eax;
* (uint32_t*) &brand[16*i + 4*1] = e.ebx;
* (uint32_t*) &brand[16*i + 4*2] = e.ecx;
* (uint32_t*) &brand[16*i + 4*3] = e.edx;
};
brand[sizeof(brand)-1] = 0;
printf("Brand String : [%s]\n", brand);
}
{
CpuInfo f1(1);
printf("CMOV : %d\n", (f1.edx >> 15) & 1);
printf("SSE2 : %d\n", (f1.edx >> 26) & 1);
printf("SSE4.1 : %d\n", (f1.ecx >> 19) & 1);
printf("SSE4.2 : %d\n", (f1.ecx >> 20) & 1);
printf("FMA : %d\n", (f1.ecx >> 12) & 1);
printf("AVX : %d\n", (f1.ecx >> 28) & 1);
printf("RDRAND : %d\n", (f1.ecx >> 30) & 1);
}
{
CpuInfo ef(7, 0);
printf("avx512_f : %d\n", (ef.ebx >> 16) & 1);
printf("avx512_dq : %d\n", (ef.ebx >> 17) & 1);
printf("avx512_ifma : %d\n", (ef.ebx >> 21) & 1);
printf("avx512_pf : %d\n", (ef.ebx >> 26) & 1);
printf("avx512_er : %d\n", (ef.ebx >> 27) & 1);
printf("avx512_cd : %d\n", (ef.ebx >> 28) & 1);
printf("avx512_bw : %d\n", (ef.ebx >> 30) & 1);
printf("avx512_vl : %d\n", (ef.ebx >> 31) & 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment