1*eca53ba6SRoland Levillain# cpu_features 2*eca53ba6SRoland Levillain 3*eca53ba6SRoland LevillainA cross-platform C library to retrieve CPU features (such as available 4*eca53ba6SRoland Levillaininstructions) at runtime. 5*eca53ba6SRoland Levillain 6*eca53ba6SRoland Levillain# GitHub-CI Status 7*eca53ba6SRoland Levillain 8*eca53ba6SRoland Levillain[comment]: <> (The following lines are generated by "scripts/generate_badges.d" that you can run online https://run.dlang.io/) 9*eca53ba6SRoland Levillain 10*eca53ba6SRoland Levillain| | Linux | FreeBSD | MacOS | Windows | 11*eca53ba6SRoland Levillain| :-- | --: | --: | --: | --: | 12*eca53ba6SRoland Levillain| amd64 | [![CMake][i1a0]][l1a0]<br/>[![Bazel][i1a1]][l1a1] | [![CMake][i2a0]][l2a0]<br/>![Bazel][d1] | [![CMake][i3a0]][l3a0]<br/>[![Bazel][i3a1]][l3a1] | [![CMake][i4a0]][l4a0]<br/>![Bazel][d1] | 13*eca53ba6SRoland Levillain| AArch64 | [![CMake][i1b0]][l1b0]<br/>[![Bazel][i1b1]][l1b1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 14*eca53ba6SRoland Levillain| ARM | [![CMake][i1c0]][l1c0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 15*eca53ba6SRoland Levillain| MIPS | [![CMake][i1d0]][l1d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 16*eca53ba6SRoland Levillain| POWER | [![CMake][i1e0]][l1e0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 17*eca53ba6SRoland Levillain| RISCV | [![CMake][i1f0]][l1f0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 18*eca53ba6SRoland Levillain| LOONGARCH | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 19*eca53ba6SRoland Levillain| s390x | [![CMake][i1h0]][l1h0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | 20*eca53ba6SRoland Levillain 21*eca53ba6SRoland Levillain[d0]: https://img.shields.io/badge/n%2Fa-lightgrey?&logo=cmake 22*eca53ba6SRoland Levillain[d1]: https://img.shields.io/badge/n%2Fa-lightgrey?&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4= 23*eca53ba6SRoland Levillain[i1a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 24*eca53ba6SRoland Levillain[i1a1]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_linux_bazel.yml?branch=main&event=push&label=&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4= 25*eca53ba6SRoland Levillain[i1b0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/aarch64_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 26*eca53ba6SRoland Levillain[i1b1]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/aarch64_linux_bazel.yml?branch=main&event=push&label=&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4= 27*eca53ba6SRoland Levillain[i1c0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/arm_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 28*eca53ba6SRoland Levillain[i1d0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/mips_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 29*eca53ba6SRoland Levillain[i1e0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/power_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 30*eca53ba6SRoland Levillain[i1f0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/riscv_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 31*eca53ba6SRoland Levillain[i1h0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/s390x_linux_cmake.yml?branch=main&event=push&label=&logo=cmake 32*eca53ba6SRoland Levillain[i2a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_freebsd_cmake.yml?branch=main&event=push&label=&logo=cmake 33*eca53ba6SRoland Levillain[i3a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_macos_cmake.yml?branch=main&event=push&label=&logo=cmake 34*eca53ba6SRoland Levillain[i3a1]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_macos_bazel.yml?branch=main&event=push&label=&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4= 35*eca53ba6SRoland Levillain[i4a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_windows_cmake.yml?branch=main&event=push&label=&logo=cmake 36*eca53ba6SRoland Levillain[l1a0]: https://github.com/google/cpu_features/actions/workflows/amd64_linux_cmake.yml 37*eca53ba6SRoland Levillain[l1a1]: https://github.com/google/cpu_features/actions/workflows/amd64_linux_bazel.yml 38*eca53ba6SRoland Levillain[l1b0]: https://github.com/google/cpu_features/actions/workflows/aarch64_linux_cmake.yml 39*eca53ba6SRoland Levillain[l1b1]: https://github.com/google/cpu_features/actions/workflows/aarch64_linux_bazel.yml 40*eca53ba6SRoland Levillain[l1c0]: https://github.com/google/cpu_features/actions/workflows/arm_linux_cmake.yml 41*eca53ba6SRoland Levillain[l1d0]: https://github.com/google/cpu_features/actions/workflows/mips_linux_cmake.yml 42*eca53ba6SRoland Levillain[l1e0]: https://github.com/google/cpu_features/actions/workflows/power_linux_cmake.yml 43*eca53ba6SRoland Levillain[l1f0]: https://github.com/google/cpu_features/actions/workflows/riscv_linux_cmake.yml 44*eca53ba6SRoland Levillain[l1h0]: https://github.com/google/cpu_features/actions/workflows/s390x_linux_cmake.yml 45*eca53ba6SRoland Levillain[l2a0]: https://github.com/google/cpu_features/actions/workflows/amd64_freebsd_cmake.yml 46*eca53ba6SRoland Levillain[l3a0]: https://github.com/google/cpu_features/actions/workflows/amd64_macos_cmake.yml 47*eca53ba6SRoland Levillain[l3a1]: https://github.com/google/cpu_features/actions/workflows/amd64_macos_bazel.yml 48*eca53ba6SRoland Levillain[l4a0]: https://github.com/google/cpu_features/actions/workflows/amd64_windows_cmake.yml 49*eca53ba6SRoland Levillain 50*eca53ba6SRoland Levillain## Table of Contents 51*eca53ba6SRoland Levillain 52*eca53ba6SRoland Levillain- [Design Rationale](#rationale) 53*eca53ba6SRoland Levillain- [Code samples](#codesample) 54*eca53ba6SRoland Levillain- [Running sample code](#usagesample) 55*eca53ba6SRoland Levillain- [What's supported](#support) 56*eca53ba6SRoland Levillain- [Android NDK's drop in replacement](#ndk) 57*eca53ba6SRoland Levillain- [License](#license) 58*eca53ba6SRoland Levillain- [Build with cmake](#cmake) 59*eca53ba6SRoland Levillain- [Community Bindings](#bindings) 60*eca53ba6SRoland Levillain 61*eca53ba6SRoland Levillain<a name="rationale"></a> 62*eca53ba6SRoland Levillain## Design Rationale 63*eca53ba6SRoland Levillain 64*eca53ba6SRoland Levillain- **Simple to use.** See the snippets below for examples. 65*eca53ba6SRoland Levillain- **Extensible.** Easy to add missing features or architectures. 66*eca53ba6SRoland Levillain- **Compatible with old compilers** and available on many architectures so it 67*eca53ba6SRoland Levillain can be used widely. To ensure that cpu_features works on as many platforms 68*eca53ba6SRoland Levillain as possible, we implemented it in a highly portable version of C: C99. 69*eca53ba6SRoland Levillain- **Sandbox-compatible.** The library uses a variety of strategies to cope 70*eca53ba6SRoland Levillain with sandboxed environments or when `cpuid` is unavailable. This is useful 71*eca53ba6SRoland Levillain when running integration tests in hermetic environments. 72*eca53ba6SRoland Levillain- **Thread safe, no memory allocation, and raises no exceptions.** 73*eca53ba6SRoland Levillain cpu_features is suitable for implementing fundamental libc functions like 74*eca53ba6SRoland Levillain `malloc`, `memcpy`, and `memcmp`. 75*eca53ba6SRoland Levillain- **Unit tested.** 76*eca53ba6SRoland Levillain 77*eca53ba6SRoland Levillain<a name="codesample"></a> 78*eca53ba6SRoland Levillain## Code samples 79*eca53ba6SRoland Levillain 80*eca53ba6SRoland Levillain**Note:** For C++ code, the library functions are defined in the `cpu_features` namespace. 81*eca53ba6SRoland Levillain 82*eca53ba6SRoland Levillain### Checking features at runtime 83*eca53ba6SRoland Levillain 84*eca53ba6SRoland LevillainHere's a simple example that executes a codepath if the CPU supports both the 85*eca53ba6SRoland LevillainAES and the SSE4.2 instruction sets: 86*eca53ba6SRoland Levillain 87*eca53ba6SRoland Levillain```c 88*eca53ba6SRoland Levillain#include "cpuinfo_x86.h" 89*eca53ba6SRoland Levillain 90*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;` 91*eca53ba6SRoland Levillainstatic const X86Features features = GetX86Info().features; 92*eca53ba6SRoland Levillain 93*eca53ba6SRoland Levillainvoid Compute(void) { 94*eca53ba6SRoland Levillain if (features.aes && features.sse4_2) { 95*eca53ba6SRoland Levillain // Run optimized code. 96*eca53ba6SRoland Levillain } else { 97*eca53ba6SRoland Levillain // Run standard code. 98*eca53ba6SRoland Levillain } 99*eca53ba6SRoland Levillain} 100*eca53ba6SRoland Levillain``` 101*eca53ba6SRoland Levillain 102*eca53ba6SRoland Levillain### Caching for faster evaluation of complex checks 103*eca53ba6SRoland Levillain 104*eca53ba6SRoland LevillainIf you wish, you can read all the features at once into a global variable, and 105*eca53ba6SRoland Levillainthen query for the specific features you care about. Below, we store all the ARM 106*eca53ba6SRoland Levillainfeatures and then check whether AES and NEON are supported. 107*eca53ba6SRoland Levillain 108*eca53ba6SRoland Levillain```c 109*eca53ba6SRoland Levillain#include <stdbool.h> 110*eca53ba6SRoland Levillain#include "cpuinfo_arm.h" 111*eca53ba6SRoland Levillain 112*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;` 113*eca53ba6SRoland Levillainstatic const ArmFeatures features = GetArmInfo().features; 114*eca53ba6SRoland Levillainstatic const bool has_aes_and_neon = features.aes && features.neon; 115*eca53ba6SRoland Levillain 116*eca53ba6SRoland Levillain// use has_aes_and_neon. 117*eca53ba6SRoland Levillain``` 118*eca53ba6SRoland Levillain 119*eca53ba6SRoland LevillainThis is a good approach to take if you're checking for combinations of features 120*eca53ba6SRoland Levillainwhen using a compiler that is slow to extract individual bits from bit-packed 121*eca53ba6SRoland Levillainstructures. 122*eca53ba6SRoland Levillain 123*eca53ba6SRoland Levillain### Checking compile time flags 124*eca53ba6SRoland Levillain 125*eca53ba6SRoland LevillainThe following code determines whether the compiler was told to use the AVX 126*eca53ba6SRoland Levillaininstruction set (e.g., `g++ -mavx`) and sets `has_avx` accordingly. 127*eca53ba6SRoland Levillain 128*eca53ba6SRoland Levillain```c 129*eca53ba6SRoland Levillain#include <stdbool.h> 130*eca53ba6SRoland Levillain#include "cpuinfo_x86.h" 131*eca53ba6SRoland Levillain 132*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;` 133*eca53ba6SRoland Levillainstatic const X86Features features = GetX86Info().features; 134*eca53ba6SRoland Levillainstatic const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx; 135*eca53ba6SRoland Levillain 136*eca53ba6SRoland Levillain// use has_avx. 137*eca53ba6SRoland Levillain``` 138*eca53ba6SRoland Levillain 139*eca53ba6SRoland Levillain`CPU_FEATURES_COMPILED_X86_AVX` is set to 1 if the compiler was instructed to 140*eca53ba6SRoland Levillainuse AVX and 0 otherwise, combining compile time and runtime knowledge. 141*eca53ba6SRoland Levillain 142*eca53ba6SRoland Levillain### Rejecting poor hardware implementations based on microarchitecture 143*eca53ba6SRoland Levillain 144*eca53ba6SRoland LevillainOn x86, the first incarnation of a feature in a microarchitecture might not be 145*eca53ba6SRoland Levillainthe most efficient (e.g. AVX on Sandy Bridge). We provide a function to retrieve 146*eca53ba6SRoland Levillainthe underlying microarchitecture so you can decide whether to use it. 147*eca53ba6SRoland Levillain 148*eca53ba6SRoland LevillainBelow, `has_fast_avx` is set to 1 if the CPU supports the AVX instruction 149*eca53ba6SRoland Levillainset—but only if it's not Sandy Bridge. 150*eca53ba6SRoland Levillain 151*eca53ba6SRoland Levillain```c 152*eca53ba6SRoland Levillain#include <stdbool.h> 153*eca53ba6SRoland Levillain#include "cpuinfo_x86.h" 154*eca53ba6SRoland Levillain 155*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;` 156*eca53ba6SRoland Levillainstatic const X86Info info = GetX86Info(); 157*eca53ba6SRoland Levillainstatic const X86Microarchitecture uarch = GetX86Microarchitecture(&info); 158*eca53ba6SRoland Levillainstatic const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB; 159*eca53ba6SRoland Levillain 160*eca53ba6SRoland Levillain// use has_fast_avx. 161*eca53ba6SRoland Levillain``` 162*eca53ba6SRoland Levillain 163*eca53ba6SRoland LevillainThis feature is currently available only for x86 microarchitectures. 164*eca53ba6SRoland Levillain 165*eca53ba6SRoland Levillain<a name="usagesample"></a> 166*eca53ba6SRoland Levillain### Running sample code 167*eca53ba6SRoland Levillain 168*eca53ba6SRoland LevillainBuilding `cpu_features` (check [quickstart](#quickstart) below) brings a small executable to test the library. 169*eca53ba6SRoland Levillain 170*eca53ba6SRoland Levillain```shell 171*eca53ba6SRoland Levillain % ./build/list_cpu_features 172*eca53ba6SRoland Levillainarch : x86 173*eca53ba6SRoland Levillainbrand : Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz 174*eca53ba6SRoland Levillainfamily : 6 (0x06) 175*eca53ba6SRoland Levillainmodel : 45 (0x2D) 176*eca53ba6SRoland Levillainstepping : 7 (0x07) 177*eca53ba6SRoland Levillainuarch : INTEL_SNB 178*eca53ba6SRoland Levillainflags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3 179*eca53ba6SRoland Levillain``` 180*eca53ba6SRoland Levillain 181*eca53ba6SRoland Levillain```shell 182*eca53ba6SRoland Levillain% ./build/list_cpu_features --json 183*eca53ba6SRoland Levillain{"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"]} 184*eca53ba6SRoland Levillain``` 185*eca53ba6SRoland Levillain 186*eca53ba6SRoland Levillain<a name="support"></a> 187*eca53ba6SRoland Levillain## What's supported 188*eca53ba6SRoland Levillain 189*eca53ba6SRoland Levillain| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | Loongarch | s390x | 190*eca53ba6SRoland Levillain|---------|:----:|:-------:|:-------:|:-------:|:-------:|:-------:|:---------:|:-------:| 191*eca53ba6SRoland Levillain| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | 192*eca53ba6SRoland Levillain| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | not yet | 193*eca53ba6SRoland Levillain| MacOs | yes² | yes⁵ | N/A | N/A | N/A | N/A | N/A | N/A | 194*eca53ba6SRoland Levillain| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A | N/A | 195*eca53ba6SRoland Levillain| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A | N/A | 196*eca53ba6SRoland Levillain| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A | N/A | 197*eca53ba6SRoland Levillain 198*eca53ba6SRoland Levillain1. **Features revealed from Linux.** We gather data from several sources 199*eca53ba6SRoland Levillain depending on availability: 200*eca53ba6SRoland Levillain + from glibc's 201*eca53ba6SRoland Levillain [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html) 202*eca53ba6SRoland Levillain + by parsing `/proc/self/auxv` 203*eca53ba6SRoland Levillain + by parsing `/proc/cpuinfo` 204*eca53ba6SRoland Levillain2. **Features revealed from CPU.** features are retrieved by using the `cpuid` 205*eca53ba6SRoland Levillain instruction. 206*eca53ba6SRoland Levillain3. **Microarchitecture detection.** On x86 some features are not always 207*eca53ba6SRoland Levillain implemented efficiently in hardware (e.g. AVX on Sandybridge). Exposing the 208*eca53ba6SRoland Levillain microarchitecture allows the client to reject particular microarchitectures. 209*eca53ba6SRoland Levillain4. All flavors of Mips are supported, little and big endian as well as 32/64 210*eca53ba6SRoland Levillain bits. 211*eca53ba6SRoland Levillain5. **Features revealed from sysctl.** features are retrieved by the `sysctl` 212*eca53ba6SRoland Levillain instruction. 213*eca53ba6SRoland Levillain 214*eca53ba6SRoland Levillain<a name="ndk"></a> 215*eca53ba6SRoland Levillain## Android NDK's drop in replacement 216*eca53ba6SRoland Levillain 217*eca53ba6SRoland Levillain[cpu_features](https://github.com/google/cpu_features) is now officially 218*eca53ba6SRoland Levillainsupporting Android and offers a drop in replacement of for the NDK's [cpu-features.h](https://android.googlesource.com/platform/ndk/+/main/sources/android/cpufeatures/cpu-features.h) 219*eca53ba6SRoland Levillain, see [ndk_compat](ndk_compat) folder for details. 220*eca53ba6SRoland Levillain 221*eca53ba6SRoland Levillain<a name="license"></a> 222*eca53ba6SRoland Levillain## License 223*eca53ba6SRoland Levillain 224*eca53ba6SRoland LevillainThe cpu_features library is licensed under the terms of the Apache license. 225*eca53ba6SRoland LevillainSee [LICENSE](LICENSE) for more information. 226*eca53ba6SRoland Levillain 227*eca53ba6SRoland Levillain<a name="cmake"></a> 228*eca53ba6SRoland Levillain## Build with CMake 229*eca53ba6SRoland Levillain 230*eca53ba6SRoland LevillainPlease check the [CMake build instructions](cmake/README.md). 231*eca53ba6SRoland Levillain 232*eca53ba6SRoland Levillain<a name="quickstart"></a> 233*eca53ba6SRoland Levillain### Quickstart 234*eca53ba6SRoland Levillain 235*eca53ba6SRoland Levillain- Run `list_cpu_features` 236*eca53ba6SRoland Levillain ```sh 237*eca53ba6SRoland Levillain cmake -S. -Bbuild -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release 238*eca53ba6SRoland Levillain cmake --build build --config Release -j 239*eca53ba6SRoland Levillain ./build/list_cpu_features --json 240*eca53ba6SRoland Levillain ``` 241*eca53ba6SRoland Levillain 242*eca53ba6SRoland Levillain _Note_: Use `--target ALL_BUILD` on the second line for `Visual Studio` and `XCode`. 243*eca53ba6SRoland Levillain 244*eca53ba6SRoland Levillain- run tests 245*eca53ba6SRoland Levillain ```sh 246*eca53ba6SRoland Levillain cmake -S. -Bbuild -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Debug 247*eca53ba6SRoland Levillain cmake --build build --config Debug -j 248*eca53ba6SRoland Levillain cmake --build build --config Debug --target test 249*eca53ba6SRoland Levillain ``` 250*eca53ba6SRoland Levillain 251*eca53ba6SRoland Levillain _Note_: Use `--target RUN_TESTS` on the last line for `Visual Studio` and `--target RUN_TEST` for `XCode`. 252*eca53ba6SRoland Levillain 253*eca53ba6SRoland Levillain 254*eca53ba6SRoland Levillain- install `cpu_features` 255*eca53ba6SRoland Levillain ```sh 256*eca53ba6SRoland Levillain cmake --build build --config Release --target install -v 257*eca53ba6SRoland Levillain ``` 258*eca53ba6SRoland Levillain 259*eca53ba6SRoland Levillain _Note_: Use `--target INSTALL` for `Visual Studio`. 260*eca53ba6SRoland Levillain 261*eca53ba6SRoland Levillain _Note_: When using `Makefile` or `XCode` generator, you can use 262*eca53ba6SRoland Levillain [`DESTDIR`](https://www.gnu.org/software/make/manual/html_node/DESTDIR.html) 263*eca53ba6SRoland Levillain to install on a local repository.<br> 264*eca53ba6SRoland Levillain e.g. 265*eca53ba6SRoland Levillain ```sh 266*eca53ba6SRoland Levillain cmake --build build --config Release --target install -v -- DESTDIR=install 267*eca53ba6SRoland Levillain ``` 268*eca53ba6SRoland Levillain 269*eca53ba6SRoland Levillain<a name="bindings"></a> 270*eca53ba6SRoland Levillain## Community bindings 271*eca53ba6SRoland Levillain 272*eca53ba6SRoland LevillainLinks provided here are not affiliated with Google but are kindly provided by the OSS Community. 273*eca53ba6SRoland Levillain 274*eca53ba6SRoland Levillain - .Net 275*eca53ba6SRoland Levillain - https://github.com/toor1245/cpu_features.NET 276*eca53ba6SRoland Levillain - Python 277*eca53ba6SRoland Levillain - https://github.com/Narasimha1997/py_cpu 278*eca53ba6SRoland Levillain - Java 279*eca53ba6SRoland Levillain - https://github.com/aecsocket/cpu-features-java 280*eca53ba6SRoland Levillain 281*eca53ba6SRoland Levillain 282*eca53ba6SRoland Levillain_Send PR to showcase your wrapper here_ 283