jaulib v1.3.0
Jau Support Library (C++, Java, ..)
cpuid.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2022 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef JAU_CPUID_HPP_
26#define JAU_CPUID_HPP_
27
28#include <jau/byte_util.hpp>
29#include <string>
30
31namespace jau::cpu {
32
33 /** \addtogroup SysUtils
34 *
35 * @{
36 */
37
38 /**
39 * Returns the compile time pointer architecture size in bits.
40 * e.g. 64-bit for LP64 and 32-bit for LP32.
41 *
42 * Implementations uses `sizeof(void*)`, i.e. the address bus size,
43 * the common denominator across all LP64, ILP64 and LLP64 for 64-bit.
44 */
45 constexpr size_t pointer_bit_size() noexcept { return sizeof(void*) * 8; }
46
47 enum class cpu_family_t : uint16_t {
48 /** Undefined */
49 none = 0,
50
51 /** ARM 32bit */
52 arm32 = 1,
53 /** ARM 64bit */
54 arm64 = 2,
55
56 /** AMD/Intel 32-bit */
57 x86_32 = 10,
58 /** AMD/Intel 64-bit */
59 x86_64 = 11,
60 /** Itanium */
61 ia64 = 12,
62
63 /** Power PC 32bit */
64 ppc32 = 20,
65 /** Power PC 32bit */
66 ppc64 = 21,
67
68 /** SPARC 32bit */
69 sparc32 = 30,
70 /** SPARC 32bit */
71 sparc64 = 31,
72
73 /** Mips 32bit */
74 mips32 = 40,
75 /** Mips 64bit */
76 mips64 = 41,
77
78 /** Hitachi SuperH 32bit */
79 superh32 = 50,
80 /** Hitachi SuperH 64bit */
81 superh64 = 51,
82
83 /** WebAssembly 32-bit */
84 wasm32 = 60,
85 /** WebAssembly 64-bit */
86 wasm64 = 61
87
88 };
89 constexpr uint16_t number(const cpu_family_t rhs) noexcept {
90 return static_cast<uint16_t>(rhs);
91 }
92 constexpr cpu_family_t operator ~(const cpu_family_t rhs) noexcept {
93 return static_cast<cpu_family_t> ( ~number(rhs) );
94 }
95 constexpr cpu_family_t operator ^(const cpu_family_t lhs, const cpu_family_t rhs) noexcept {
96 return static_cast<cpu_family_t> ( number(lhs) ^ number(rhs) );
97 }
98 constexpr cpu_family_t operator |(const cpu_family_t lhs, const cpu_family_t rhs) noexcept {
99 return static_cast<cpu_family_t> ( number(lhs) | number(rhs) );
100 }
101 constexpr cpu_family_t operator &(const cpu_family_t lhs, const cpu_family_t rhs) noexcept {
102 return static_cast<cpu_family_t> ( number(lhs) & number(rhs) );
103 }
104 constexpr cpu_family_t& operator |=(cpu_family_t& lhs, const cpu_family_t rhs) noexcept {
105 lhs = static_cast<cpu_family_t> ( number(lhs) | number(rhs) );
106 return lhs;
107 }
108 constexpr cpu_family_t& operator &=(cpu_family_t& lhs, const cpu_family_t rhs) noexcept {
109 lhs = static_cast<cpu_family_t> ( number(lhs) & number(rhs) );
110 return lhs;
111 }
112 constexpr cpu_family_t& operator ^=(cpu_family_t& lhs, const cpu_family_t rhs) noexcept {
113 lhs = static_cast<cpu_family_t> ( number(lhs) ^ number(rhs) );
114 return lhs;
115 }
116 constexpr bool operator ==(const cpu_family_t lhs, const cpu_family_t rhs) noexcept {
117 return number(lhs) == number(rhs);
118 }
119 constexpr bool operator !=(const cpu_family_t lhs, const cpu_family_t rhs) noexcept {
120 return !( lhs == rhs );
121 }
122 constexpr bool is_set(const cpu_family_t mask, const cpu_family_t bit) noexcept {
123 return bit == ( mask & bit );
124 }
125 std::string to_string(const cpu_family_t v) noexcept;
126
127 enum class arm32_hwcap1_t : uint64_t {
128 none = 0,
129 swp = (1 << 0),
130 half = (1 << 1),
131 thumb = (1 << 2),
132 bits26 = (1 << 3),
133 fmult = (1 << 4),
134 fpa = (1 << 5),
135 vfp = (1 << 6),
136 edsp = (1 << 7),
137 java = (1 << 8),
138 iwmmxt = (1 << 9),
139 crunch = (1 << 10),
140 thumbee = (1 << 11),
141 neon = (1 << 12),
142 vfp_v3 = (1 << 13),
143 vfp_v3_d16 = (1 << 14),
144 tls = (1 << 15),
145 vfp_v4 = (1 << 16),
146 idiva = (1 << 17),
147 idivt = (1 << 18),
148 vfp_d32 = (1 << 19),
149 lpae = (1 << 20),
150 evtstrm = (1 << 21),
151
152 at_hwcap_1 = 16
153 };
154 constexpr uint64_t number(const arm32_hwcap1_t rhs) noexcept {
155 return static_cast<uint64_t>(rhs);
156 }
157 constexpr arm32_hwcap1_t operator ~(const arm32_hwcap1_t rhs) noexcept {
158 return static_cast<arm32_hwcap1_t> ( ~number(rhs) );
159 }
160 constexpr arm32_hwcap1_t operator ^(const arm32_hwcap1_t lhs, const arm32_hwcap1_t rhs) noexcept {
161 return static_cast<arm32_hwcap1_t> ( number(lhs) ^ number(rhs) );
162 }
163 constexpr arm32_hwcap1_t operator |(const arm32_hwcap1_t lhs, const arm32_hwcap1_t rhs) noexcept {
164 return static_cast<arm32_hwcap1_t> ( number(lhs) | number(rhs) );
165 }
166 constexpr arm32_hwcap1_t operator &(const arm32_hwcap1_t lhs, const arm32_hwcap1_t rhs) noexcept {
167 return static_cast<arm32_hwcap1_t> ( number(lhs) & number(rhs) );
168 }
169 constexpr arm32_hwcap1_t& operator |=(arm32_hwcap1_t& lhs, const arm32_hwcap1_t rhs) noexcept {
170 lhs = static_cast<arm32_hwcap1_t> ( number(lhs) | number(rhs) );
171 return lhs;
172 }
173 constexpr arm32_hwcap1_t& operator &=(arm32_hwcap1_t& lhs, const arm32_hwcap1_t rhs) noexcept {
174 lhs = static_cast<arm32_hwcap1_t> ( number(lhs) & number(rhs) );
175 return lhs;
176 }
177 constexpr arm32_hwcap1_t& operator ^=(arm32_hwcap1_t& lhs, const arm32_hwcap1_t rhs) noexcept {
178 lhs = static_cast<arm32_hwcap1_t> ( number(lhs) ^ number(rhs) );
179 return lhs;
180 }
181 constexpr bool operator ==(const arm32_hwcap1_t lhs, const arm32_hwcap1_t rhs) noexcept {
182 return number(lhs) == number(rhs);
183 }
184 constexpr bool operator !=(const arm32_hwcap1_t lhs, const arm32_hwcap1_t rhs) noexcept {
185 return !( lhs == rhs );
186 }
187 constexpr bool is_set(const arm32_hwcap1_t mask, const arm32_hwcap1_t bit) noexcept {
188 return bit == ( mask & bit );
189 }
190 std::string to_string(const arm32_hwcap1_t hwcaps) noexcept;
191
192 enum class arm32_hwcap2_t : uint64_t {
193 none = 0,
194 aes = (1 << 0),
195 pmull = (1 << 1),
196 sha1 = (1 << 2),
197 sha2 = (1 << 3),
198 crc32 = (1 << 4),
199
200 at_hwcap_2 = 26
201 };
202 constexpr uint64_t number(const arm32_hwcap2_t rhs) noexcept {
203 return static_cast<uint64_t>(rhs);
204 }
205 constexpr arm32_hwcap2_t operator ~(const arm32_hwcap2_t rhs) noexcept {
206 return static_cast<arm32_hwcap2_t> ( ~number(rhs) );
207 }
208 constexpr arm32_hwcap2_t operator ^(const arm32_hwcap2_t lhs, const arm32_hwcap2_t rhs) noexcept {
209 return static_cast<arm32_hwcap2_t> ( number(lhs) ^ number(rhs) );
210 }
211 constexpr arm32_hwcap2_t operator |(const arm32_hwcap2_t lhs, const arm32_hwcap2_t rhs) noexcept {
212 return static_cast<arm32_hwcap2_t> ( number(lhs) | number(rhs) );
213 }
214 constexpr arm32_hwcap2_t operator &(const arm32_hwcap2_t lhs, const arm32_hwcap2_t rhs) noexcept {
215 return static_cast<arm32_hwcap2_t> ( number(lhs) & number(rhs) );
216 }
217 constexpr arm32_hwcap2_t& operator |=(arm32_hwcap2_t& lhs, const arm32_hwcap2_t rhs) noexcept {
218 lhs = static_cast<arm32_hwcap2_t> ( number(lhs) | number(rhs) );
219 return lhs;
220 }
221 constexpr arm32_hwcap2_t& operator &=(arm32_hwcap2_t& lhs, const arm32_hwcap2_t rhs) noexcept {
222 lhs = static_cast<arm32_hwcap2_t> ( number(lhs) & number(rhs) );
223 return lhs;
224 }
225 constexpr arm32_hwcap2_t& operator ^=(arm32_hwcap2_t& lhs, const arm32_hwcap2_t rhs) noexcept {
226 lhs = static_cast<arm32_hwcap2_t> ( number(lhs) ^ number(rhs) );
227 return lhs;
228 }
229 constexpr bool operator ==(const arm32_hwcap2_t lhs, const arm32_hwcap2_t rhs) noexcept {
230 return number(lhs) == number(rhs);
231 }
232 constexpr bool operator !=(const arm32_hwcap2_t lhs, const arm32_hwcap2_t rhs) noexcept {
233 return !( lhs == rhs );
234 }
235 constexpr bool is_set(const arm32_hwcap2_t mask, const arm32_hwcap2_t bit) noexcept {
236 return bit == ( mask & bit );
237 }
238 std::string to_string(const arm32_hwcap2_t hwcaps) noexcept;
239
240 enum class arm64_hwcap_t : uint64_t {
241 none = 0,
242 fp = (1 << 0),
243 asimd = (1 << 1),
244 evtstrm = (1 << 2),
245 aes = (1 << 3),
246 pmull = (1 << 4),
247 sha1 = (1 << 5),
248 sha2 = (1 << 6),
249 crc32 = (1 << 7),
250 atomics = (1 << 8),
251 fphp = (1 << 9),
252 asimdhp = (1 << 10),
253 cpuid = (1 << 11),
254 asimdrdm = (1 << 12),
255 jscvt = (1 << 13),
256 fcma = (1 << 14),
257 lrcpc = (1 << 15),
258 dcpop = (1 << 16),
259 sha3 = (1 << 17),
260 sm3 = (1 << 18),
261 sm4 = (1 << 19),
262 asimddp = (1 << 20),
263 sha512 = (1 << 21),
264 sve = (1 << 22),
265 asimdfhm = (1 << 23),
266 dit = (1 << 24),
267 uscat = (1 << 25),
268 ilrcpc = (1 << 26),
269 flagm = (1 << 27),
270 ssbs = (1 << 28),
271 sb = (1 << 29),
272 paca = (1 << 30),
273 pacg = (1UL << 31),
274
275 at_hwcap = 16
276 };
277 constexpr uint64_t number(const arm64_hwcap_t rhs) noexcept {
278 return static_cast<uint64_t>(rhs);
279 }
280 constexpr arm64_hwcap_t operator ~(const arm64_hwcap_t rhs) noexcept {
281 return static_cast<arm64_hwcap_t> ( ~number(rhs) );
282 }
283 constexpr arm64_hwcap_t operator ^(const arm64_hwcap_t lhs, const arm64_hwcap_t rhs) noexcept {
284 return static_cast<arm64_hwcap_t> ( number(lhs) ^ number(rhs) );
285 }
286 constexpr arm64_hwcap_t operator |(const arm64_hwcap_t lhs, const arm64_hwcap_t rhs) noexcept {
287 return static_cast<arm64_hwcap_t> ( number(lhs) | number(rhs) );
288 }
289 constexpr arm64_hwcap_t operator &(const arm64_hwcap_t lhs, const arm64_hwcap_t rhs) noexcept {
290 return static_cast<arm64_hwcap_t> ( number(lhs) & number(rhs) );
291 }
292 constexpr arm64_hwcap_t& operator |=(arm64_hwcap_t& lhs, const arm64_hwcap_t rhs) noexcept {
293 lhs = static_cast<arm64_hwcap_t> ( number(lhs) | number(rhs) );
294 return lhs;
295 }
296 constexpr arm64_hwcap_t& operator &=(arm64_hwcap_t& lhs, const arm64_hwcap_t rhs) noexcept {
297 lhs = static_cast<arm64_hwcap_t> ( number(lhs) & number(rhs) );
298 return lhs;
299 }
300 constexpr arm64_hwcap_t& operator ^=(arm64_hwcap_t& lhs, const arm64_hwcap_t rhs) noexcept {
301 lhs = static_cast<arm64_hwcap_t> ( number(lhs) ^ number(rhs) );
302 return lhs;
303 }
304 constexpr bool operator ==(const arm64_hwcap_t lhs, const arm64_hwcap_t rhs) noexcept {
305 return number(lhs) == number(rhs);
306 }
307 constexpr bool operator !=(const arm64_hwcap_t lhs, const arm64_hwcap_t rhs) noexcept {
308 return !( lhs == rhs );
309 }
310 constexpr bool is_set(const arm64_hwcap_t mask, const arm64_hwcap_t bit) noexcept {
311 return bit == ( mask & bit );
312 }
313 std::string to_string(const arm64_hwcap_t hwcaps) noexcept;
314
315 /** Singleton CpuInfo caching all jau::cpu information */
316 class CpuInfo {
317 public:
318 /** See pointer_bit_size() */
320 /** Size of a page in bytes or zero if not available */
321 size_t page_size;
322 /** True if successfully queried l1_share_max and l1_apart_min. */
324 /** Maximum size of contiguous memory to promote true sharing if has_l1_minmax, or zero */
326 /** Minimum offset between two objects to avoid false sharing if has_l1_minmax, or zero */
328 /** Number of available concurrent threads (cores) or zero if information is not available, using C++11 std::thread::hardware_concurrency() */
330 /** Number of available/online cores from system call */
332 /** Number of installed/configured cores from system call */
334 /** cpu_family_t derived from [Architectures](https://sourceforge.net/p/predef/wiki/Architectures/) predefined compiler macros. */
337 /** True if successfully queried arm32_hwcap1 and arm32_hwcap1 on cpu_family_t::arm32. */
339 /** arm32_hwcap1_t info if available, i.e. has_arm32_hwcap */
341 /** arm32_hwcap2_t info if available, i.e. has_arm32_hwcap */
343 /** True if successfully queried arm64_hwcap on cpu_family_t::arm64. */
345 /** arm64_hwcap_t info if available, i.e. has_arm64_hwcap */
347
348 private:
349 CpuInfo() noexcept;
350
351 public:
352 CpuInfo(const CpuInfo&) = delete;
353 void operator=(const CpuInfo&) = delete;
354
355 /** Returns reference to const singleton instance */
356 static inline const CpuInfo& get() noexcept {
357 static CpuInfo ci;
358 return ci;
359 }
360
361 /** Returns maximum number of available/online cores, i.e. max(sys_online_cores, concurrent_threads). */
362 inline size_t online_core_count() const noexcept {
364 }
365
366 std::string toString(std::string& sb, bool details_only=false) const noexcept;
367 std::string toString() const noexcept {
368 std::string sb; toString(sb); return sb;
369 }
370 };
371
372 inline std::string get_cpu_info(std::string& sb) noexcept {
373 return CpuInfo::get().toString(sb);
374 }
375 inline std::string get_cpu_info() noexcept {
376 std::string sb; CpuInfo::get().toString(sb); return sb;
377 }
378
379 /**@}*/
380
381} // namespace jau::cpu
382
383#endif /* JAU_CPUID_HPP_ */
384
Singleton CpuInfo caching all jau::cpu information.
Definition: cpuid.hpp:316
size_t pointer_bits
See pointer_bit_size()
Definition: cpuid.hpp:319
size_t sys_online_cores
Number of available/online cores from system call.
Definition: cpuid.hpp:331
static const CpuInfo & get() noexcept
Returns reference to const singleton instance.
Definition: cpuid.hpp:356
std::string toString() const noexcept
Definition: cpuid.hpp:367
size_t l1_apart_min
Minimum offset between two objects to avoid false sharing if has_l1_minmax, or zero.
Definition: cpuid.hpp:327
size_t online_core_count() const noexcept
Returns maximum number of available/online cores, i.e.
Definition: cpuid.hpp:362
cpu_family_t family
cpu_family_t derived from Architectures predefined compiler macros.
Definition: cpuid.hpp:335
bool has_l1_minmax
True if successfully queried l1_share_max and l1_apart_min.
Definition: cpuid.hpp:323
arm32_hwcap1_t arm32_hwcap1
arm32_hwcap1_t info if available, i.e.
Definition: cpuid.hpp:340
std::string toString(std::string &sb, bool details_only=false) const noexcept
Definition: cpuid.cpp:393
bool has_arm32_hwcap
True if successfully queried arm32_hwcap1 and arm32_hwcap1 on cpu_family_t::arm32.
Definition: cpuid.hpp:338
size_t sys_max_cores
Number of installed/configured cores from system call.
Definition: cpuid.hpp:333
size_t page_size
Size of a page in bytes or zero if not available.
Definition: cpuid.hpp:321
jau::endian_t byte_order
Definition: cpuid.hpp:336
arm64_hwcap_t arm64_hwcap
arm64_hwcap_t info if available, i.e.
Definition: cpuid.hpp:346
size_t l1_share_max
Maximum size of contiguous memory to promote true sharing if has_l1_minmax, or zero.
Definition: cpuid.hpp:325
bool has_arm64_hwcap
True if successfully queried arm64_hwcap on cpu_family_t::arm64.
Definition: cpuid.hpp:344
arm32_hwcap2_t arm32_hwcap2
arm32_hwcap2_t info if available, i.e.
Definition: cpuid.hpp:342
size_t concurrent_threads
Number of available concurrent threads (cores) or zero if information is not available,...
Definition: cpuid.hpp:329
endian_t
Endian identifier, indicating endianess of all scalar types.
Definition: byte_util.hpp:203
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
Definition: base_math.hpp:191
arm32_hwcap2_t
Definition: cpuid.hpp:192
constexpr cpu_family_t & operator^=(cpu_family_t &lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:112
constexpr cpu_family_t operator&(const cpu_family_t lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:101
constexpr bool operator!=(const cpu_family_t lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:119
arm64_hwcap_t
Definition: cpuid.hpp:240
std::string to_string(const cpu_family_t v) noexcept
Definition: cpuid.cpp:149
constexpr cpu_family_t operator~(const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:92
constexpr bool operator==(const cpu_family_t lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:116
constexpr size_t pointer_bit_size() noexcept
Returns the compile time pointer architecture size in bits.
Definition: cpuid.hpp:45
constexpr bool is_set(const cpu_family_t mask, const cpu_family_t bit) noexcept
Definition: cpuid.hpp:122
constexpr cpu_family_t operator|(const cpu_family_t lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:98
constexpr cpu_family_t & operator|=(cpu_family_t &lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:104
constexpr uint16_t number(const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:89
cpu_family_t
Definition: cpuid.hpp:47
constexpr cpu_family_t & operator&=(cpu_family_t &lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:108
std::string get_cpu_info(std::string &sb) noexcept
Definition: cpuid.hpp:372
arm32_hwcap1_t
Definition: cpuid.hpp:127
constexpr cpu_family_t operator^(const cpu_family_t lhs, const cpu_family_t rhs) noexcept
Definition: cpuid.hpp:95
@ x86_64
AMD/Intel 64-bit.
@ x86_32
AMD/Intel 32-bit.
@ sparc32
SPARC 32bit.
@ wasm64
WebAssembly 64-bit.
@ superh32
Hitachi SuperH 32bit.
@ superh64
Hitachi SuperH 64bit.
@ wasm32
WebAssembly 32-bit.
@ ppc64
Power PC 32bit.
@ sparc64
SPARC 32bit.
@ ppc32
Power PC 32bit.
STL namespace.