vir-simd 0.4.189
Parallelism TS 2 extensions and simd fallback implementation
Loading...
Searching...
No Matches
simd_benchmarking.h
1/* SPDX-License-Identifier: LGPL-3.0-or-later */
2/* Copyright © 2019–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
3 * Matthias Kretz <m.kretz@gsi.de>
4 */
5
6#ifndef VIR_SIMD_BENCHMARKING_H_
7#define VIR_SIMD_BENCHMARKING_H_
8
9#if __cpp_concepts >= 201907 and defined __GNUC__
10#include "simd.h"
11
12#define VIR_HAVE_SIMD_BENCHMARKING 1
13
14namespace vir
15{
16#if defined(__x86_64__) or defined(__i686__)
17#define VIR_SIMD_REG "v,x,"
18#else
19#define VIR_SIMD_REG
20#endif
21
22 template <typename T>
23 VIR_ALWAYS_INLINE void
24 fake_modify_one(T& x)
25 {
26 if constexpr (std::is_floating_point_v<T>)
27 asm volatile("" : "+" VIR_SIMD_REG "g,m"(x));
28 else if constexpr (stdx::is_simd_v<T> || stdx::is_simd_mask_v<T>)
29 {
30#if defined _GLIBCXX_EXPERIMENTAL_SIMD && __cpp_lib_experimental_parallel_simd >= 201803
31 auto& d = stdx::__data(x);
32 if constexpr (requires {{d._S_tuple_size};})
33 stdx::__for_each(d, [](auto, auto& element) {
34 fake_modify_one(element);
35 });
36 else if constexpr (requires {{d._M_data};})
37 fake_modify_one(d._M_data);
38 else
39 fake_modify_one(d);
40#else
41 // assuming vir::stdx::simd implementation
42 if constexpr (sizeof(x) < 16)
43 asm volatile("" : "+g"(x));
44 else
45 asm volatile("" : "+" VIR_SIMD_REG "g,m"(x));
46#endif
47 }
48 else if constexpr (sizeof(x) >= 16)
49 asm volatile("" : "+" VIR_SIMD_REG "g,m"(x));
50 else
51 asm volatile("" : "+g"(x));
52 }
53
54 template <typename... Ts>
55 VIR_ALWAYS_INLINE void
56 fake_modify(Ts&... more)
57 { (fake_modify_one(more), ...); }
58
59 template <typename T>
60 VIR_ALWAYS_INLINE void
61 fake_read_one(const T& x)
62 {
63 if constexpr (std::is_floating_point_v<T>)
64 asm volatile("" ::VIR_SIMD_REG "g,m"(x));
65 else if constexpr (stdx::is_simd_v<T> || stdx::is_simd_mask_v<T>)
66 {
67#if defined _GLIBCXX_EXPERIMENTAL_SIMD && __cpp_lib_experimental_parallel_simd >= 201803
68 const auto& d = stdx::__data(x);
69 if constexpr (requires {{d._S_tuple_size};})
70 stdx::__for_each(d, [](auto, const auto& element) {
71 fake_read_one(element);
72 });
73 else if constexpr (requires {{d._M_data};})
74 fake_read_one(d._M_data);
75 else
76 fake_read_one(d);
77#else
78 // assuming vir::stdx::simd implementation
79 if constexpr (sizeof(x) < 16)
80 asm volatile("" ::"g"(x));
81 else
82 asm volatile("" ::VIR_SIMD_REG "g,m"(x));
83#endif
84 }
85 else if constexpr (sizeof(x) >= 16)
86 asm volatile("" ::VIR_SIMD_REG"g,m"(x));
87 else
88 asm volatile("" ::"g"(x));
89 }
90#undef VIR_SIMD_REG
91
92 template <typename... Ts>
93 VIR_ALWAYS_INLINE void
94 fake_read(const Ts&... more)
95 { (fake_read_one(more), ...); }
96
97} // namespace vir
98#endif // __cpp_concepts
99#endif // VIR_SIMD_BENCHMARKING_H_
100
101// vim: noet cc=101 tw=100 sw=2 ts=8
This namespace collects libraries and tools authored by Matthias Kretz.
Definition constexpr_wrapper.h:21