Unfortunately, this isn't really a simple task if you want it to be portable. Compilers usually have something to help you out, but the functions are all different.
MSVC has a __cpuid
intrinsic on x86/x86_64, but of course it's not supported on ARM. TBH I'm not sure how to get CPU capabilities on MSVC targeting ARM (or any non-x86 arch).
Compilers other than MSVC generally masquerade as GCC, so most of them will support the __builtin_cpu_init
/__bulitin_cpu_supports
intrinsics.
For other compilers you may have to use inline assembly to generate a CPUID instruction and handle the results yourself. That gets you through x86/x86_64.
Things for other architectures are a bit more complicated. For ARM, the instruction to get CPU information isn't generally accessible to unprivileged code. For glibc, you can use getauxval
with AT_HWCAP
and/or AT_HWCAP2
. For non-glibc Linux, you may have to parse /proc/self/auxv and/or /proc/cpuinfo.
One pretty robust solution is Google's new cpu_features library.
If you can sacrifice some portability, there is a cpu module in portable-snippets (which I wrote) which could help. It's not nearly as robust as cpu_features, but it's a lot easier to integrate into your project. It should work pretty much everywhere on x86/x86_64 CPUs, but ARM support is limited to glibc, and other architectures aren't yet supported.