1 # cpu_features [![Build Status](https://travis-ci.org/google/cpu_features.svg?branch=master)](https://travis-ci.org/google/cpu_features) [![Build status](https://ci.appveyor.com/api/projects/status/46d1owsj7n8dsylq/branch/master?svg=true)](https://ci.appveyor.com/project/gchatelet/cpu-features/branch/master)
3 A cross-platform C library to retrieve CPU features (such as available
4 instructions) at runtime.
8 - [Design Rationale](#rationale)
9 - [Code samples](#codesample)
10 - [Running sample code](#usagesample)
11 - [What's supported](#support)
13 - [Build with cmake](#cmake)
15 <a name="rationale"></a>
18 - **Simple to use.** See the snippets below for examples.
19 - **Extensible.** Easy to add missing features or architectures.
20 - **Compatible with old compilers** and available on many architectures so it
21 can be used widely. To ensure that cpu_features works on as many platforms
22 as possible, we implemented it in a highly portable version of C: C99.
23 - **Sandbox-compatible.** The library uses a variety of strategies to cope
24 with sandboxed environments or when `cpuid` is unavailable. This is useful
25 when running integration tests in hermetic environments.
26 - **Thread safe, no memory allocation, and raises no exceptions.**
27 cpu_features is suitable for implementing fundamental libc functions like
28 `malloc`, `memcpy`, and `memcmp`.
31 <a name="codesample"></a>
32 ### Checking features at runtime
34 Here's a simple example that executes a codepath if the CPU supports both the
35 AES and the SSE4.2 instruction sets:
38 #include "cpuinfo_x86.h"
40 static const X86Features features = GetX86Info().features;
43 if (features.aes && features.sse4_2) {
44 // Run optimized code.
51 ### Caching for faster evaluation of complex checks
53 If you wish, you can read all the features at once into a global variable, and
54 then query for the specific features you care about. Below, we store all the ARM
55 features and then check whether AES and NEON are supported.
59 #include "cpuinfo_arm.h"
61 static const ArmFeatures features = GetArmInfo().features;
62 static const bool has_aes_and_neon = features.aes && features.neon;
64 // use has_aes_and_neon.
67 This is a good approach to take if you're checking for combinations of features
68 when using a compiler that is slow to extract individual bits from bit-packed
71 ### Checking compile time flags
73 The following code determines whether the compiler was told to use the AVX
74 instruction set (e.g., `g++ -mavx`) and sets `has_avx` accordingly.
78 #include "cpuinfo_x86.h"
80 static const X86Features features = GetX86Info().features;
81 static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx;
86 `CPU_FEATURES_COMPILED_X86_AVX` is set to 1 if the compiler was instructed to
87 use AVX and 0 otherwise, combining compile time and runtime knowledge.
89 ### Rejecting poor hardware implementations based on microarchitecture
91 On x86, the first incarnation of a feature in a microarchitecture might not be
92 the most efficient (e.g. AVX on Sandy Bridge). We provide a function to retrieve
93 the underlying microarchitecture so you can decide whether to use it.
95 Below, `has_fast_avx` is set to 1 if the CPU supports the AVX instruction
96 set—but only if it's not Sandy Bridge.
100 #include "cpuinfo_x86.h"
102 static const X86Info info = GetX86Info();
103 static const X86Microarchitecture uarch = GetX86Microarchitecture(&info);
104 static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB;
109 This feature is currently available only for x86 microarchitectures.
111 <a name="usagesample"></a>
112 ### Running sample code
114 Building `cpu_features` brings a small executable to test the library.
117 % ./build/list_cpu_features
119 brand : Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz
124 flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
128 % ./build/list_cpu_features --json
129 {"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"]}
132 <a name="support"></a>
135 | | x86³ | ARM | AArch64 | MIPSel | POWER |
136 |---------|:----:|:-------:|:-------:|:------:|:-------:|
137 | Android | yes² | yes¹ | yes¹ | yes¹ | N/A |
138 | iOS | N/A | not yet | not yet | N/A | N/A |
139 | Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ |
140 | MacOs | yes² | N/A | not yet | N/A | no |
141 | Windows | yes² | not yet | not yet | N/A | N/A |
143 1. **Features revealed from Linux.** We gather data from several sources
144 depending on availability:
146 [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html)
147 + by parsing `/proc/self/auxv`
148 + by parsing `/proc/cpuinfo`
149 2. **Features revealed from CPU.** features are retrieved by using the `cpuid`
151 3. **Microarchitecture detection.** On x86 some features are not always
152 implemented efficiently in hardware (e.g. AVX on Sandybridge). Exposing the
153 microarchitecture allows the client to reject particular microarchitectures.
156 <a name="license"></a>
159 The cpu_features library is licensed under the terms of the Apache license.
160 See [LICENSE](LICENSE) for more information.
165 Please check the [CMake build instructions](cmake/README.md).