XUtils

cpu_features

A cross platform C99 library to get cpu features at runtime. [`Apache 2.0`](https://directory.fsf.org/wiki/License:Apache-2.0)


cpu_features

A cross-platform C library to retrieve CPU features (such as available instructions) at runtime.

GitHub-CI Status

Linux FreeBSD MacOS Windows
amd64 CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
AArch64 CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
ARM CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
MIPS CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
POWER CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
RISCV CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
LOONGARCH CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel
s390x CMake
Bazel
CMake
Bazel
CMake
Bazel
CMake
Bazel

Design Rationale

  • Simple to use. See the snippets below for examples.
  • Extensible. Easy to add missing features or architectures.
  • Compatible with old compilers and available on many architectures so it can be used widely. To ensure that cpu_features works on as many platforms as possible, we implemented it in a highly portable version of C: C99.
  • Sandbox-compatible. The library uses a variety of strategies to cope with sandboxed environments or when cpuid is unavailable. This is useful when running integration tests in hermetic environments.
  • Thread safe, no memory allocation, and raises no exceptions. cpu_features is suitable for implementing fundamental libc functions like malloc, memcpy, and memcmp.
  • Unit tested.

Code samples

Note: For C++ code, the library functions are defined in the cpu_features namespace.

#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.

} }


#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.

Checking compile time flags

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.

#include

Build with CMake

Please check the CMake build instructions.

Quickstart

  • 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

Community bindings

Links provided here are not affiliated with Google but are kindly provided by the OSS Community.

Send PR to showcase your wrapper here


Articles

  • coming soon...