A cross-platform C library to retrieve CPU features (such as available instructions) at runtime.
Linux | FreeBSD | MacOS | Windows | |
---|---|---|---|---|
amd64 | ||||
AArch64 | ||||
ARM | ||||
MIPS | ||||
POWER | ||||
RISCV | ||||
LOONGARCH | ||||
s390x |
cpuid
is unavailable. This is useful
when running integration tests in hermetic environments.malloc
, memcpy
, and memcmp
.Note: For C++ code, the library functions are defined in the cpu_features
namespace.
Here's a simple example that executes a codepath if the CPU supports both the AES and the SSE4.2 instruction sets:
#include "cpuinfo_x86.h"
// For C++, add `using namespace cpu_features;`
static const X86Features features = GetX86Info().features;
void Compute(void) {
if (features.aes && features.sse4_2) {
// Run optimized code.
} else {
// Run standard code.
}
}
If you wish, you can read all the features at once into a global variable, and then query for the specific features you care about. Below, we store all the ARM features and then check whether AES and NEON are supported.
#include <stdbool.h>
#include "cpuinfo_arm.h"
// For C++, add `using namespace cpu_features;`
static const ArmFeatures features = GetArmInfo().features;
static const bool has_aes_and_neon = features.aes && features.neon;
// use has_aes_and_neon.
This is a good approach to take if you're checking for combinations of features when using a compiler that is slow to extract individual bits from bit-packed structures.
The following code determines whether the compiler was told to use the AVX
instruction set (e.g., g++ -mavx
) and sets has_avx
accordingly.
#include <stdbool.h>
#include "cpuinfo_x86.h"
// For C++, add `using namespace cpu_features;`
static const X86Features features = GetX86Info().features;
static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx;
// use has_avx.
CPU_FEATURES_COMPILED_X86_AVX
is set to 1 if the compiler was instructed to
use AVX and 0 otherwise, combining compile time and runtime knowledge.
On x86, the first incarnation of a feature in a microarchitecture might not be the most efficient (e.g. AVX on Sandy Bridge). We provide a function to retrieve the underlying microarchitecture so you can decide whether to use it.
Below, has_fast_avx
is set to 1 if the CPU supports the AVX instruction
set—but only if it's not Sandy Bridge.
#include <stdbool.h>
#include "cpuinfo_x86.h"
// For C++, add `using namespace cpu_features;`
static const X86Info info = GetX86Info();
static const X86Microarchitecture uarch = GetX86Microarchitecture(&info);
static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB;
// use has_fast_avx.
This feature is currently available only for x86 microarchitectures.
Building cpu_features
(check quickstart below) brings a small executable to test the library.
% ./build/list_cpu_features
arch : x86
brand : Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz
family : 6 (0x06)
model : 45 (0x2D)
stepping : 7 (0x07)
uarch : INTEL_SNB
flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
% ./build/list_cpu_features --json
{"arch":"x86","brand":" Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz","family":6,"model":45,"stepping":7,"uarch":"INTEL_SNB","flags":["aes","avx","cx16","smx","sse4_1","sse4_2","ssse3"]}
x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | Loongarch | s390x | |
---|---|---|---|---|---|---|---|---|
Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | not yet |
MacOs | yes² | yes⁵ | N/A | N/A | N/A | N/A | N/A | N/A |
Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A | N/A |
Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A | N/A |
iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A | N/A |
/proc/self/auxv
/proc/cpuinfo
cpuid
instruction.sysctl
instruction.cpu_features is now officially supporting Android and offers a drop in replacement of for the NDK's cpu-features.h , see ndk_compat folder for details.
The cpu_features library is licensed under the terms of the Apache license. See LICENSE for more information.
Please check the CMake build instructions.
Run list_cpu_features
cmake -S. -Bbuild -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j
./build/list_cpu_features --json
Note: Use --target ALL_BUILD
on the second line for Visual Studio
and XCode
.
run tests
cmake -S. -Bbuild -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build --config Debug -j
cmake --build build --config Debug --target test
Note: Use --target RUN_TESTS
on the last line for Visual Studio
and --target RUN_TEST
for XCode
.
install cpu_features
cmake --build build --config Release --target install -v
Note: Use --target INSTALL
for Visual Studio
.
Note: When using Makefile
or XCode
generator, you can use
DESTDIR
to install on a local repository.
e.g.
cmake --build build --config Release --target install -v -- DESTDIR=install
Links provided here are not affiliated with Google but are kindly provided by the OSS Community.
Send PR to showcase your wrapper here