mirror of
https://github.com/google/cpu_features.git
synced 2025-04-27 07:02:30 +02:00
cpu features
A cross platform C89 library to get cpu features at runtime.
Checking features at runtime.
#include "cpuinfo_x86.h"
static const X86Features features = GetX86Info().features;
void Compute(void) {
if(features.aes && features.sse4_2) {
// Run optimized code.
} else {
// Run standard code.
}
}
Caching for faster evaluation of complex checks.
Features are bit packed and some compilers generate poor code when combining them. A simple solution is to read them once and store the result in a global variable.
#include "cpuinfo_arm.h"
static const ArmFeatures features = GetArmInfo().features;
static const bool has_aes_and_neon = features.aes && features.neon;
// use has_aes_and_neon.
Checking compile time flags as well.
#include "cpuinfo_x86.h"
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 is instructed to use
AVX, 0 otherwise. This allows combining compile time and runtime knowledge.
Use x86 microarchitecture to reject poor hardware implementations.
#include "cpuinfo_x86.h"
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.
On x86, the first incarnation of a feature in a microarchitecture may not be very efficient (e.g. AVX on Sandybridge). We provide a function to retrieve the underlying microarchitecture so clients can decide whether they want to use it or not.
What does it currently support
x86 | ARM | aarch64 | mips | POWER | |
---|---|---|---|---|---|
Features From cpu | yes | no* | no* | no yet | not yet |
Features From Linux | no | yes | yes | yes | not yet |
Micro Architecture Detection | yes | no | no | no | not yet |
Windows support | yes | no | no | no | not yet |
- Features From Cpuid: features are retrieved by using the cpuid instruction. (*) Unfortunately this instruction is privileged for some architectures; in this case we fall back to Linux.
- Features From Linux: we gather data from several sources depending on
what's available:
- from glibc's getauxval
- by parsing
/proc/self/auxv
- by parsing
/proc/cpuinfo
- Micro Architecture Detection: On x86 some features are not always implemented efficiently in hardware (e.g. AVX on Sandybridge). Exposing the microarchitecture allows the client to reject some microarchitectures.
Design Rationale
- Simple to use, API should be straightforward from the snippets above.
- Unit tested.
- Extensible. It should be easy to add missing features or architectures.
- Compatible with old compilers and available on many architectures so it can be used widely. We target gnu89.
- Works in sandboxed environment: some architectures rely on parsing files that may not be available in a sandboxed environment. It is useful when running integration tests in hermetic environments.
- Thread safe, no allocation, no exception: suitable for implementation of fundamental libc functions like malloc, memcpy, memcmp...
Description
Languages
C++
58.5%
C
29.8%
CMake
4.4%
Shell
4.1%
Makefile
2.5%
Other
0.7%