xref: /aosp_15_r20/external/cpuinfo/README.md (revision 2b54f0db79fd8303838913b20ff3780cddaa909f)
1*2b54f0dbSXin Li# CPU INFOrmation library
2*2b54f0dbSXin Li
3*2b54f0dbSXin Li[![BSD (2 clause) License](https://img.shields.io/badge/License-BSD%202--Clause%20%22Simplified%22%20License-blue.svg)](https://github.com/pytorch/cpuinfo/blob/master/LICENSE)
4*2b54f0dbSXin Li[![Linux/Mac build status](https://img.shields.io/travis/pytorch/cpuinfo.svg)](https://travis-ci.org/pytorch/cpuinfo)
5*2b54f0dbSXin Li[![Windows build status](https://ci.appveyor.com/api/projects/status/g5khy9nr0xm458t7/branch/master?svg=true)](https://ci.appveyor.com/project/MaratDukhan/cpuinfo/branch/master)
6*2b54f0dbSXin Li
7*2b54f0dbSXin Licpuinfo is a library to detect essential for performance optimization information about host CPU.
8*2b54f0dbSXin Li
9*2b54f0dbSXin Li## Features
10*2b54f0dbSXin Li
11*2b54f0dbSXin Li- **Cross-platform** availability:
12*2b54f0dbSXin Li  - Linux, Windows, macOS, Android, and iOS operating systems
13*2b54f0dbSXin Li  - x86, x86-64, ARM, and ARM64 architectures
14*2b54f0dbSXin Li- Modern **C/C++ interface**
15*2b54f0dbSXin Li  - Thread-safe
16*2b54f0dbSXin Li  - No memory allocation after initialization
17*2b54f0dbSXin Li  - No exceptions thrown
18*2b54f0dbSXin Li- Detection of **supported instruction sets**, up to AVX512 (x86) and ARMv8.3 extensions
19*2b54f0dbSXin Li- Detection of SoC and core information:
20*2b54f0dbSXin Li  - **Processor (SoC) name**
21*2b54f0dbSXin Li  - Vendor and **microarchitecture** for each CPU core
22*2b54f0dbSXin Li  - ID (**MIDR** on ARM, **CPUID** leaf 1 EAX value on x86) for each CPU core
23*2b54f0dbSXin Li- Detection of **cache information**:
24*2b54f0dbSXin Li  - Cache type (instruction/data/unified), size and line size
25*2b54f0dbSXin Li  - Cache associativity
26*2b54f0dbSXin Li  - Cores and logical processors (hyper-threads) sharing the cache
27*2b54f0dbSXin Li- Detection of **topology information** (relative between logical processors, cores, and processor packages)
28*2b54f0dbSXin Li- Well-tested **production-quality** code:
29*2b54f0dbSXin Li  - 60+ mock tests based on data from real devices
30*2b54f0dbSXin Li  - Includes work-arounds for common bugs in hardware and OS kernels
31*2b54f0dbSXin Li  - Supports systems with heterogenous cores, such as **big.LITTLE** and Max.Med.Min
32*2b54f0dbSXin Li- Permissive **open-source** license (Simplified BSD)
33*2b54f0dbSXin Li
34*2b54f0dbSXin Li## Examples
35*2b54f0dbSXin Li
36*2b54f0dbSXin LiLog processor name:
37*2b54f0dbSXin Li
38*2b54f0dbSXin Li```c
39*2b54f0dbSXin Licpuinfo_initialize();
40*2b54f0dbSXin Liprintf("Running on %s CPU\n", cpuinfo_get_package(0)->name);
41*2b54f0dbSXin Li```
42*2b54f0dbSXin Li
43*2b54f0dbSXin LiDetect if target is a 32-bit or 64-bit ARM system:
44*2b54f0dbSXin Li
45*2b54f0dbSXin Li```c
46*2b54f0dbSXin Li#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
47*2b54f0dbSXin Li    /* 32-bit ARM-specific code here */
48*2b54f0dbSXin Li#endif
49*2b54f0dbSXin Li```
50*2b54f0dbSXin Li
51*2b54f0dbSXin LiCheck if the host CPU supports ARM NEON
52*2b54f0dbSXin Li
53*2b54f0dbSXin Li```c
54*2b54f0dbSXin Licpuinfo_initialize();
55*2b54f0dbSXin Liif (cpuinfo_has_arm_neon()) {
56*2b54f0dbSXin Li    neon_implementation(arguments);
57*2b54f0dbSXin Li}
58*2b54f0dbSXin Li```
59*2b54f0dbSXin Li
60*2b54f0dbSXin LiCheck if the host CPU supports x86 AVX
61*2b54f0dbSXin Li
62*2b54f0dbSXin Li```c
63*2b54f0dbSXin Licpuinfo_initialize();
64*2b54f0dbSXin Liif (cpuinfo_has_x86_avx()) {
65*2b54f0dbSXin Li    avx_implementation(arguments);
66*2b54f0dbSXin Li}
67*2b54f0dbSXin Li```
68*2b54f0dbSXin Li
69*2b54f0dbSXin LiCheck if the thread runs on a Cortex-A53 core
70*2b54f0dbSXin Li
71*2b54f0dbSXin Li```c
72*2b54f0dbSXin Licpuinfo_initialize();
73*2b54f0dbSXin Liswitch (cpuinfo_get_current_core()->uarch) {
74*2b54f0dbSXin Li    case cpuinfo_uarch_cortex_a53:
75*2b54f0dbSXin Li        cortex_a53_implementation(arguments);
76*2b54f0dbSXin Li        break;
77*2b54f0dbSXin Li    default:
78*2b54f0dbSXin Li        generic_implementation(arguments);
79*2b54f0dbSXin Li        break;
80*2b54f0dbSXin Li}
81*2b54f0dbSXin Li```
82*2b54f0dbSXin Li
83*2b54f0dbSXin LiGet the size of level 1 data cache on the fastest core in the processor (e.g. big core in big.LITTLE ARM systems):
84*2b54f0dbSXin Li
85*2b54f0dbSXin Li```c
86*2b54f0dbSXin Licpuinfo_initialize();
87*2b54f0dbSXin Liconst size_t l1_size = cpuinfo_get_processor(0)->cache.l1d->size;
88*2b54f0dbSXin Li```
89*2b54f0dbSXin Li
90*2b54f0dbSXin LiPin thread to cores sharing L2 cache with the current core (Linux or Android)
91*2b54f0dbSXin Li
92*2b54f0dbSXin Li```c
93*2b54f0dbSXin Licpuinfo_initialize();
94*2b54f0dbSXin Licpu_set_t cpu_set;
95*2b54f0dbSXin LiCPU_ZERO(&cpu_set);
96*2b54f0dbSXin Liconst struct cpuinfo_cache* current_l2 = cpuinfo_get_current_processor()->cache.l2;
97*2b54f0dbSXin Lifor (uint32_t i = 0; i < current_l2->processor_count; i++) {
98*2b54f0dbSXin Li    CPU_SET(cpuinfo_get_processor(current_l2->processor_start + i)->linux_id, &cpu_set);
99*2b54f0dbSXin Li}
100*2b54f0dbSXin Lipthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set);
101*2b54f0dbSXin Li```
102*2b54f0dbSXin Li
103*2b54f0dbSXin Li## Use via pkg-config
104*2b54f0dbSXin Li
105*2b54f0dbSXin LiIf you would like to provide your project's build environment with the necessary compiler and linker flags in a portable manner, the library by default when built enables `CPUINFO_BUILD_PKG_CONFIG` and will generate a [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) manifest (_libcpuinfo.pc_). Here are several examples of how to use it:
106*2b54f0dbSXin Li
107*2b54f0dbSXin Li### Command Line
108*2b54f0dbSXin Li
109*2b54f0dbSXin LiIf you used your distro's package manager to install the library, you can verify that it is available to your build environment like so:
110*2b54f0dbSXin Li
111*2b54f0dbSXin Li```console
112*2b54f0dbSXin Li$ pkg-config --cflags --libs libcpuinfo
113*2b54f0dbSXin Li-I/usr/include/x86_64-linux-gnu/ -L/lib/x86_64-linux-gnu/ -lcpuinfo
114*2b54f0dbSXin Li```
115*2b54f0dbSXin Li
116*2b54f0dbSXin LiIf you have installed the library from source into a non-standard prefix, pkg-config may need help finding it:
117*2b54f0dbSXin Li
118*2b54f0dbSXin Li```console
119*2b54f0dbSXin Li$ PKG_CONFIG_PATH="/home/me/projects/cpuinfo/prefix/lib/pkgconfig/:$PKG_CONFIG_PATH" pkg-config --cflags --libs libcpuinfo
120*2b54f0dbSXin Li-I/home/me/projects/cpuinfo/prefix/include -L/home/me/projects/cpuinfo/prefix/lib -lcpuinfo
121*2b54f0dbSXin Li```
122*2b54f0dbSXin Li
123*2b54f0dbSXin Li### GNU Autotools
124*2b54f0dbSXin Li
125*2b54f0dbSXin LiTo [use](https://autotools.io/pkgconfig/pkg_check_modules.html) with the GNU Autotools include the following snippet in your project's `configure.ac`:
126*2b54f0dbSXin Li
127*2b54f0dbSXin Li```makefile
128*2b54f0dbSXin Li# CPU INFOrmation library...
129*2b54f0dbSXin LiPKG_CHECK_MODULES(
130*2b54f0dbSXin Li    [libcpuinfo], [libcpuinfo], [],
131*2b54f0dbSXin Li    [AC_MSG_ERROR([libcpuinfo missing...])])
132*2b54f0dbSXin LiYOURPROJECT_CXXFLAGS="$YOURPROJECT_CXXFLAGS $libcpuinfo_CFLAGS"
133*2b54f0dbSXin LiYOURPROJECT_LIBS="$YOURPROJECT_LIBS $libcpuinfo_LIBS"
134*2b54f0dbSXin Li```
135*2b54f0dbSXin Li
136*2b54f0dbSXin Li### Meson
137*2b54f0dbSXin Li
138*2b54f0dbSXin LiTo use with Meson you just need to add `dependency('libcpuinfo')` as a dependency for your executable.
139*2b54f0dbSXin Li
140*2b54f0dbSXin Li```meson
141*2b54f0dbSXin Liproject(
142*2b54f0dbSXin Li    'MyCpuInfoProject',
143*2b54f0dbSXin Li    'cpp',
144*2b54f0dbSXin Li    meson_version: '>=0.55.0'
145*2b54f0dbSXin Li)
146*2b54f0dbSXin Li
147*2b54f0dbSXin Liexecutable(
148*2b54f0dbSXin Li    'MyCpuInfoExecutable',
149*2b54f0dbSXin Li    sources: 'main.cpp',
150*2b54f0dbSXin Li    dependencies: dependency('libcpuinfo')
151*2b54f0dbSXin Li)
152*2b54f0dbSXin Li```
153*2b54f0dbSXin Li
154*2b54f0dbSXin Li### Bazel
155*2b54f0dbSXin Li
156*2b54f0dbSXin LiThis project can be built using [Bazel](https://bazel.build/install).
157*2b54f0dbSXin Li
158*2b54f0dbSXin LiYou can also use this library as a dependency to your Bazel project. Add to the `WORKSPACE` file:
159*2b54f0dbSXin Li
160*2b54f0dbSXin Li```python
161*2b54f0dbSXin Liload("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
162*2b54f0dbSXin Li
163*2b54f0dbSXin Ligit_repository(
164*2b54f0dbSXin Li    name = "org_pytorch_cpuinfo",
165*2b54f0dbSXin Li    branch = "master",
166*2b54f0dbSXin Li    remote = "https://github.com/Vertexwahn/cpuinfo.git",
167*2b54f0dbSXin Li)
168*2b54f0dbSXin Li```
169*2b54f0dbSXin Li
170*2b54f0dbSXin LiAnd to your `BUILD` file:
171*2b54f0dbSXin Li
172*2b54f0dbSXin Li```python
173*2b54f0dbSXin Licc_binary(
174*2b54f0dbSXin Li    name = "cpuinfo_test",
175*2b54f0dbSXin Li    srcs = [
176*2b54f0dbSXin Li        # ...
177*2b54f0dbSXin Li    ],
178*2b54f0dbSXin Li    deps = [
179*2b54f0dbSXin Li        "@org_pytorch_cpuinfo//:cpuinfo",
180*2b54f0dbSXin Li    ],
181*2b54f0dbSXin Li)
182*2b54f0dbSXin Li```
183*2b54f0dbSXin Li
184*2b54f0dbSXin Li### CMake
185*2b54f0dbSXin Li
186*2b54f0dbSXin LiTo use with CMake use the [FindPkgConfig](https://cmake.org/cmake/help/latest/module/FindPkgConfig.html) module. Here is an example:
187*2b54f0dbSXin Li
188*2b54f0dbSXin Li```cmake
189*2b54f0dbSXin Licmake_minimum_required(VERSION 3.6)
190*2b54f0dbSXin Liproject("MyCpuInfoProject")
191*2b54f0dbSXin Li
192*2b54f0dbSXin Lifind_package(PkgConfig)
193*2b54f0dbSXin Lipkg_check_modules(CpuInfo REQUIRED IMPORTED_TARGET libcpuinfo)
194*2b54f0dbSXin Li
195*2b54f0dbSXin Liadd_executable(${PROJECT_NAME} main.cpp)
196*2b54f0dbSXin Litarget_link_libraries(${PROJECT_NAME} PkgConfig::CpuInfo)
197*2b54f0dbSXin Li```
198*2b54f0dbSXin Li
199*2b54f0dbSXin Li### Makefile
200*2b54f0dbSXin Li
201*2b54f0dbSXin LiTo use within a vanilla makefile, you can call pkg-config directly to supply compiler and linker flags using shell substitution.
202*2b54f0dbSXin Li
203*2b54f0dbSXin Li```makefile
204*2b54f0dbSXin LiCFLAGS=-g3 -Wall -Wextra -Werror ...
205*2b54f0dbSXin LiLDFLAGS=-lfoo ...
206*2b54f0dbSXin Li...
207*2b54f0dbSXin LiCFLAGS+= $(pkg-config --cflags libcpuinfo)
208*2b54f0dbSXin LiLDFLAGS+= $(pkg-config --libs libcpuinfo)
209*2b54f0dbSXin Li```
210*2b54f0dbSXin Li
211*2b54f0dbSXin Li## Exposed information
212*2b54f0dbSXin Li- [x] Processor (SoC) name
213*2b54f0dbSXin Li- [x] Microarchitecture
214*2b54f0dbSXin Li- [x] Usable instruction sets
215*2b54f0dbSXin Li- [ ] CPU frequency
216*2b54f0dbSXin Li- [x] Cache
217*2b54f0dbSXin Li  - [x] Size
218*2b54f0dbSXin Li  - [x] Associativity
219*2b54f0dbSXin Li  - [x] Line size
220*2b54f0dbSXin Li  - [x] Number of partitions
221*2b54f0dbSXin Li  - [x] Flags (unified, inclusive, complex hash function)
222*2b54f0dbSXin Li  - [x] Topology (logical processors that share this cache level)
223*2b54f0dbSXin Li- [ ] TLB
224*2b54f0dbSXin Li  - [ ] Number of entries
225*2b54f0dbSXin Li  - [ ] Associativity
226*2b54f0dbSXin Li  - [ ] Covered page types (instruction, data)
227*2b54f0dbSXin Li  - [ ] Covered page sizes
228*2b54f0dbSXin Li- [x] Topology information
229*2b54f0dbSXin Li  - [x] Logical processors
230*2b54f0dbSXin Li  - [x] Cores
231*2b54f0dbSXin Li  - [x] Packages (sockets)
232*2b54f0dbSXin Li
233*2b54f0dbSXin Li## Supported environments:
234*2b54f0dbSXin Li- [x] Android
235*2b54f0dbSXin Li  - [x] x86 ABI
236*2b54f0dbSXin Li  - [x] x86_64 ABI
237*2b54f0dbSXin Li  - [x] armeabi ABI
238*2b54f0dbSXin Li  - [x] armeabiv7-a ABI
239*2b54f0dbSXin Li  - [x] arm64-v8a ABI
240*2b54f0dbSXin Li  - [ ] ~~mips ABI~~
241*2b54f0dbSXin Li  - [ ] ~~mips64 ABI~~
242*2b54f0dbSXin Li- [x] Linux
243*2b54f0dbSXin Li  - [x] x86
244*2b54f0dbSXin Li  - [x] x86-64
245*2b54f0dbSXin Li  - [x] 32-bit ARM (ARMv5T and later)
246*2b54f0dbSXin Li  - [x] ARM64
247*2b54f0dbSXin Li  - [ ] PowerPC64
248*2b54f0dbSXin Li- [x] iOS
249*2b54f0dbSXin Li  - [x] x86 (iPhone simulator)
250*2b54f0dbSXin Li  - [x] x86-64 (iPhone simulator)
251*2b54f0dbSXin Li  - [x] ARMv7
252*2b54f0dbSXin Li  - [x] ARM64
253*2b54f0dbSXin Li- [x] macOS
254*2b54f0dbSXin Li  - [x] x86
255*2b54f0dbSXin Li  - [x] x86-64
256*2b54f0dbSXin Li  - [x] ARM64 (Apple silicon)
257*2b54f0dbSXin Li- [x] Windows
258*2b54f0dbSXin Li  - [x] x86
259*2b54f0dbSXin Li  - [x] x86-64
260*2b54f0dbSXin Li  - [x] arm64
261*2b54f0dbSXin Li
262*2b54f0dbSXin Li## Methods
263*2b54f0dbSXin Li
264*2b54f0dbSXin Li- Processor (SoC) name detection
265*2b54f0dbSXin Li  - [x] Using CPUID leaves 0x80000002–0x80000004 on x86/x86-64
266*2b54f0dbSXin Li  - [x] Using `/proc/cpuinfo` on ARM
267*2b54f0dbSXin Li  - [x] Using `ro.chipname`, `ro.board.platform`, `ro.product.board`, `ro.mediatek.platform`, `ro.arch` properties (Android)
268*2b54f0dbSXin Li  - [ ] Using kernel log (`dmesg`) on ARM Linux
269*2b54f0dbSXin Li  - [x] Using Windows registry on ARM64 Windows
270*2b54f0dbSXin Li- Vendor and microarchitecture detection
271*2b54f0dbSXin Li  - [x] Intel-designed x86/x86-64 cores (up to Sunny Cove, Goldmont Plus, and Knights Mill)
272*2b54f0dbSXin Li  - [x] AMD-designed x86/x86-64 cores (up to Puma/Jaguar and Zen 2)
273*2b54f0dbSXin Li  - [ ] VIA-designed x86/x86-64 cores
274*2b54f0dbSXin Li  - [ ] Other x86 cores (DM&P, RDC, Transmeta, Cyrix, Rise)
275*2b54f0dbSXin Li  - [x] ARM-designed ARM cores (up to Cortex-A55, Cortex-A77, and Neoverse E1/N1/V1/N2)
276*2b54f0dbSXin Li  - [x] Qualcomm-designed ARM cores (Scorpion, Krait, and Kryo)
277*2b54f0dbSXin Li  - [x] Nvidia-designed ARM cores (Denver and Carmel)
278*2b54f0dbSXin Li  - [x] Samsung-designed ARM cores (Exynos)
279*2b54f0dbSXin Li  - [x] Intel-designed ARM cores (XScale up to 3rd-gen)
280*2b54f0dbSXin Li  - [x] Apple-designed ARM cores (up to Lightning and Thunder)
281*2b54f0dbSXin Li  - [x] Cavium-designed ARM cores (ThunderX)
282*2b54f0dbSXin Li  - [x] AppliedMicro-designed ARM cores (X-Gene)
283*2b54f0dbSXin Li- Instruction set detection
284*2b54f0dbSXin Li  - [x] Using CPUID (x86/x86-64)
285*2b54f0dbSXin Li  - [x] Using `/proc/cpuinfo` on 32-bit ARM EABI (Linux)
286*2b54f0dbSXin Li  - [x] Using microarchitecture heuristics on (32-bit ARM)
287*2b54f0dbSXin Li  - [x] Using `FPSID` and `WCID` registers (32-bit ARM)
288*2b54f0dbSXin Li  - [x] Using `getauxval` (Linux/ARM)
289*2b54f0dbSXin Li  - [x] Using `/proc/self/auxv` (Android/ARM)
290*2b54f0dbSXin Li  - [ ] Using instruction probing on ARM (Linux)
291*2b54f0dbSXin Li  - [ ] Using CPUID registers on ARM64 (Linux)
292*2b54f0dbSXin Li  - [x] Using IsProcessorFeaturePresent on ARM64 Windows
293*2b54f0dbSXin Li- Cache detection
294*2b54f0dbSXin Li  - [x] Using CPUID leaf 0x00000002 (x86/x86-64)
295*2b54f0dbSXin Li  - [x] Using CPUID leaf 0x00000004 (non-AMD x86/x86-64)
296*2b54f0dbSXin Li  - [ ] Using CPUID leaves 0x80000005-0x80000006 (AMD x86/x86-64)
297*2b54f0dbSXin Li  - [x] Using CPUID leaf 0x8000001D (AMD x86/x86-64)
298*2b54f0dbSXin Li  - [x] Using `/proc/cpuinfo` (Linux/pre-ARMv7)
299*2b54f0dbSXin Li  - [x] Using microarchitecture heuristics (ARM)
300*2b54f0dbSXin Li  - [x] Using chipset name (ARM)
301*2b54f0dbSXin Li  - [x] Using `sysctlbyname` (Mach)
302*2b54f0dbSXin Li  - [x] Using sysfs `typology` directories (ARM/Linux)
303*2b54f0dbSXin Li  - [ ] Using sysfs `cache` directories (Linux)
304*2b54f0dbSXin Li  - [x] Using `GetLogicalProcessorInformationEx` on ARM64 Windows
305*2b54f0dbSXin Li- TLB detection
306*2b54f0dbSXin Li  - [x] Using CPUID leaf 0x00000002 (x86/x86-64)
307*2b54f0dbSXin Li  - [ ] Using CPUID leaves 0x80000005-0x80000006 and 0x80000019 (AMD x86/x86-64)
308*2b54f0dbSXin Li  - [x] Using microarchitecture heuristics (ARM)
309*2b54f0dbSXin Li- Topology detection
310*2b54f0dbSXin Li  - [x] Using CPUID leaf 0x00000001 on x86/x86-64 (legacy APIC ID)
311*2b54f0dbSXin Li  - [x] Using CPUID leaf 0x0000000B on x86/x86-64 (Intel APIC ID)
312*2b54f0dbSXin Li  - [ ] Using CPUID leaf 0x8000001E on x86/x86-64 (AMD APIC ID)
313*2b54f0dbSXin Li  - [x] Using `/proc/cpuinfo` (Linux)
314*2b54f0dbSXin Li  - [x] Using `host_info` (Mach)
315*2b54f0dbSXin Li  - [x] Using `GetLogicalProcessorInformationEx` (Windows)
316*2b54f0dbSXin Li  - [x] Using sysfs (Linux)
317*2b54f0dbSXin Li  - [x] Using chipset name (ARM/Linux)
318*2b54f0dbSXin Li
319