MRPT  1.9.9
cpu.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "core-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
13 #include <mrpt/core/cpu.h>
14 #include <mrpt/core/format.h>
15 
16 #if defined(_MSC_VER)
17 #include <intrin.h> // __cpuidex
18 #endif
19 
20 namespace mrpt::cpu::internal
21 {
23 {
24  static CPU_analyzer o;
25  return o;
26 }
27 
28 #if defined(_MSC_VER)
29 // MSVC version
30 void CPU_analyzer::detect_impl() noexcept
31 {
32  // Based on: https://stackoverflow.com/a/7495023/1631514
33 #define cpuid(info, x) __cpuidex(info, x, 0)
34 
35  int info[4];
36  cpuid(info, 0);
37  int nIds = info[0];
38 
39  cpuid(info, 0x80000000);
40  unsigned nExIds = info[0];
41 
42  // Detect Features
43  using namespace mrpt::cpu;
44 
45  if (nIds >= 0x00000001)
46  {
47  cpuid(info, 0x00000001);
48  feat(feature::MMX) = !!(info[3] & (1 << 23));
49  feat(feature::POPCNT) = !!(info[2] & (1 << 23));
50  feat(feature::SSE) = !!(info[3] & (1 << 25));
51 #if MRPT_HAS_SSE2
52  feat(feature::SSE2) = !!(info[3] & (1 << 26));
53 #endif
54 #if MRPT_HAS_SSE3
55  feat(feature::SSE3) = !!(info[2] & (1 << 0));
56  feat(feature::SSSE3) = !!(info[2] & (1 << 9));
57 #endif
58 #if MRPT_HAS_SSE4_1
59  feat(feature::SSE4_1) = !!(info[2] & (1 << 19));
60 #endif
61 #if MRPT_HAS_SSE4_2
62  feat(feature::SSE4_2) = !!(info[2] & (1 << 20));
63 #endif
64 #if MRPT_HAS_AVX
65  feat(feature::AVX) = !!(info[2] & (1 << 28));
66 #endif
67  }
68  if (nIds >= 0x00000007)
69  {
70  cpuid(info, 0x00000007);
71  feat(feature::AVX2) = !!(info[1] & (1 << 5));
72  }
73 
74  // Doubt: is this required?
75  // auto xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
76 }
77 #else
78 // GCC/CLANG version
80 {
81  // __builtin_cpu_supports() checks for both: CPU and OS support
82 
83  using namespace mrpt::cpu;
84 
85  // These ones only for intel 64bit arch:
86  // Some might be usable in 32bit builds, but they might require
87  // additional checks (in MSVC) and it's not worth: why building for
88  // 32bit nowadays?
89 #if defined(__x86_64__)
90  feat(feature::MMX) = !!__builtin_cpu_supports("mmx");
91  feat(feature::POPCNT) = !!__builtin_cpu_supports("popcnt");
92  feat(feature::SSE) = !!__builtin_cpu_supports("sse");
93 #if MRPT_HAS_SSE2
94  feat(feature::SSE2) = !!__builtin_cpu_supports("sse2");
95 #endif
96 #if MRPT_HAS_SSE3
97  feat(feature::SSE3) = !!__builtin_cpu_supports("sse3");
98  feat(feature::SSSE3) = !!__builtin_cpu_supports("ssse3");
99 #endif
100 #if MRPT_HAS_SSE4_1
101  feat(feature::SSE4_1) = !!__builtin_cpu_supports("sse4.1");
102 #endif
103 #if MRPT_HAS_SSE4_2
104  feat(feature::SSE4_2) = !!__builtin_cpu_supports("sse4.2");
105 #endif
106 #if MRPT_HAS_AVX
107  feat(feature::AVX) = __builtin_cpu_supports("avx");
108 #endif
109 #if MRPT_HAS_AVX2
110  feat(feature::AVX2) = __builtin_cpu_supports("avx2");
111 #endif
112 #endif
113 }
114 #endif
115 } // namespace mrpt::cpu::internal
116 
117 std::string mrpt::cpu::features_as_string() noexcept
118 {
119  std::string s;
120  using namespace mrpt::cpu;
121  const auto& o = internal::CPU_analyzer::Instance();
122 
123  s += mrpt::format("MMX:%i ", o.feat(feature::MMX) ? 1 : 0);
124  s += mrpt::format("POPCNT:%i ", o.feat(feature::POPCNT) ? 1 : 0);
125  s += mrpt::format("SSE:%i ", o.feat(feature::SSE) ? 1 : 0);
126  s += mrpt::format("SSE2:%i ", o.feat(feature::SSE2) ? 1 : 0);
127  s += mrpt::format("SSE3:%i ", o.feat(feature::SSE3) ? 1 : 0);
128  s += mrpt::format("SSSE3:%i ", o.feat(feature::SSSE3) ? 1 : 0);
129  s += mrpt::format("SSE4_1:%i ", o.feat(feature::SSE4_1) ? 1 : 0);
130  s += mrpt::format("SSE4_2:%i ", o.feat(feature::SSE4_2) ? 1 : 0);
131  s += mrpt::format("AVX:%i ", o.feat(feature::AVX) ? 1 : 0);
132  s += mrpt::format("AVX2:%i ", o.feat(feature::AVX2) ? 1 : 0);
133 
134  return s;
135 }
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
bool & feat(mrpt::cpu::feature f) noexcept
Definition: cpu.h:51
Auxiliary class.
Definition: cpu.h:42
Definition: cpu.h:16
std::string features_as_string() noexcept
Returns a string with detected features: "MMX:1 SSE2:0 etc.".
Definition: cpu.cpp:117
void detect_impl() noexcept
Definition: cpu.cpp:79
static CPU_analyzer & Instance() noexcept
Definition: cpu.cpp:22



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 3a26b90fd Wed Mar 25 20:17:03 2020 +0100 at miƩ mar 25 23:05:41 CET 2020