MRPT  2.0.1
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  feat(feature::SSE2) = !!(info[3] & (1 << 26));
52  feat(feature::SSE3) = !!(info[2] & (1 << 0));
53  feat(feature::SSSE3) = !!(info[2] & (1 << 9));
54  feat(feature::SSE4_1) = !!(info[2] & (1 << 19));
55  feat(feature::SSE4_2) = !!(info[2] & (1 << 20));
56  feat(feature::AVX) = !!(info[2] & (1 << 28));
57  }
58  if (nIds >= 0x00000007)
59  {
60  cpuid(info, 0x00000007);
61  feat(feature::AVX2) = !!(info[1] & (1 << 5));
62  }
63 
64  // Doubt: is this required?
65  // auto xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
66 }
67 #else
68 // GCC/CLANG version
70 {
71  // __builtin_cpu_supports() checks for both: CPU and OS support
72 
73  using namespace mrpt::cpu;
74 
75  // These ones only for intel 64bit arch:
76  // Some might be usable in 32bit builds, but they might require
77  // additional checks (in MSVC) and it's not worth: why building for
78  // 32bit nowadays?
79 #if defined(__x86_64__)
80  feat(feature::MMX) = !!__builtin_cpu_supports("mmx");
81  feat(feature::POPCNT) = !!__builtin_cpu_supports("popcnt");
82  feat(feature::SSE) = !!__builtin_cpu_supports("sse");
83  feat(feature::SSE2) = !!__builtin_cpu_supports("sse2");
84  feat(feature::SSE3) = !!__builtin_cpu_supports("sse3");
85  feat(feature::SSSE3) = !!__builtin_cpu_supports("ssse3");
86  feat(feature::SSE4_1) = !!__builtin_cpu_supports("sse4.1");
87  feat(feature::SSE4_2) = !!__builtin_cpu_supports("sse4.2");
88  feat(feature::AVX) = __builtin_cpu_supports("avx");
89  feat(feature::AVX2) = __builtin_cpu_supports("avx2");
90 #endif
91 }
92 #endif
93 } // namespace mrpt::cpu::internal
94 
95 std::string mrpt::cpu::features_as_string() noexcept
96 {
97  std::string s;
98  using namespace mrpt::cpu;
99  const auto& o = internal::CPU_analyzer::Instance();
100 
101  s += mrpt::format("MMX:%i ", o.feat(feature::MMX) ? 1 : 0);
102  s += mrpt::format("POPCNT:%i ", o.feat(feature::POPCNT) ? 1 : 0);
103  s += mrpt::format("SSE:%i ", o.feat(feature::SSE) ? 1 : 0);
104  s += mrpt::format("SSE2:%i ", o.feat(feature::SSE2) ? 1 : 0);
105  s += mrpt::format("SSE3:%i ", o.feat(feature::SSE3) ? 1 : 0);
106  s += mrpt::format("SSSE3:%i ", o.feat(feature::SSSE3) ? 1 : 0);
107  s += mrpt::format("SSE4_1:%i ", o.feat(feature::SSE4_1) ? 1 : 0);
108  s += mrpt::format("SSE4_2:%i ", o.feat(feature::SSE4_2) ? 1 : 0);
109  s += mrpt::format("AVX:%i ", o.feat(feature::AVX) ? 1 : 0);
110  s += mrpt::format("AVX2:%i ", o.feat(feature::AVX2) ? 1 : 0);
111 
112  return s;
113 }
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:95
void detect_impl() noexcept
Definition: cpu.cpp:69
static CPU_analyzer & Instance() noexcept
Definition: cpu.cpp:22



Page generated by Doxygen 1.8.14 for MRPT 2.0.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020