Name Date Size #Lines LOC

..--

bazel/H25-Apr-2025-1811

cmake/H25-Apr-2025-961779

include/H25-Apr-2025-2,1101,391

ndk_compat/H25-Apr-2025-606319

scripts/H25-Apr-2025-813643

src/H25-Apr-2025-4,4763,762

test/H25-Apr-2025-3,7163,013

.clang-formatH A D25-Apr-202551 54

.dockerignoreH A D25-Apr-2025359 3229

.gitignoreH A D25-Apr-2025199 2016

.grenrc.ymlH A D25-Apr-2025388 2221

BUILD.bazelH A D25-Apr-20258.3 KiB330306

CMakeLists.txtH A D25-Apr-20258.7 KiB262228

CONTRIBUTING.mdH A D25-Apr-2025969 2417

LICENSEH A D25-Apr-202512.6 KiB231195

README.mdH A D25-Apr-202511.3 KiB273210

WORKSPACEH A D25-Apr-2025473 2014

README.md

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