Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
hist_benchmark_atomic.cxx
Go to the documentation of this file.
2#include <ROOT/RHistUtils.hxx>
3
4// Note: In principle, the benchmark library supports multithreaded benchmarks. However, the output has historically
5// been confusing (wrong): https://github.com/google/benchmark/issues/1834 This was changed / fixed in version 1.9.0:
6// https://github.com/google/benchmark/pull/1836 Even then, the minimum benchmark time is not correctly respected (in
7// the way I would expect): https://github.com/google/benchmark/issues/2117
8// Moreover, measuring contention heavily depends on the machine, cache coherency, tread placement / binding, and other
9// factors. Reproducibility is very hard to achieve with the limited control that the benchmark library offers.
10// For these reasons, the following benchmarks are not automatically run with multiple threads to benchmark contention.
11// Care should be taken when manually changing and trying to interpret the results!
12// To keep this possiblity though, the benchmarks MUST NOT use benchmark::DoNotOptimize() on non-const references to
13// shared variables: Older compilers (GCC before version 12.1.0) will load and store the value through the reference,
14// which leads to data races!
15#include <benchmark/benchmark.h>
16
17#include <cstddef>
18
19struct RHistAtomic_int : public benchmark::Fixture {
20 int fAtomic = 0;
21};
22
23BENCHMARK_DEFINE_F(RHistAtomic_int, Add)(benchmark::State &state)
24{
25 for (auto _ : state) {
26 fAtomic += 1;
27 benchmark::ClobberMemory();
28 }
29}
31
32BENCHMARK_DEFINE_F(RHistAtomic_int, AtomicAdd)(benchmark::State &state)
33{
34 for (auto _ : state) {
36 benchmark::ClobberMemory();
37 }
38}
40
41BENCHMARK_DEFINE_F(RHistAtomic_int, AtomicAddRelease)(benchmark::State &state)
42{
43 for (auto _ : state) {
45 benchmark::ClobberMemory();
46 }
47}
49
50BENCHMARK_DEFINE_F(RHistAtomic_int, AtomicLoad)(benchmark::State &state)
51{
52 int load;
53 for (auto _ : state) {
55 benchmark::ClobberMemory();
56 }
57}
59
60BENCHMARK_DEFINE_F(RHistAtomic_int, AtomicLoadAcquire)(benchmark::State &state)
61{
62 int load;
63 for (auto _ : state) {
65 benchmark::ClobberMemory();
66 }
67}
69
70BENCHMARK_DEFINE_F(RHistAtomic_int, AtomicStoreRelease)(benchmark::State &state)
71{
72 int store = 1;
73 for (auto _ : state) {
75 benchmark::ClobberMemory();
76 }
77}
79
80struct RHistAtomic_float : public benchmark::Fixture {
81 float fAtomic = 0;
82};
83
84BENCHMARK_DEFINE_F(RHistAtomic_float, Add)(benchmark::State &state)
85{
86 for (auto _ : state) {
87 fAtomic += 1.0f;
88 benchmark::ClobberMemory();
89 }
90}
92
93BENCHMARK_DEFINE_F(RHistAtomic_float, AtomicAdd)(benchmark::State &state)
94{
95 for (auto _ : state) {
97 benchmark::ClobberMemory();
98 }
99}
101
102BENCHMARK_DEFINE_F(RHistAtomic_float, AtomicAddRelease)(benchmark::State &state)
103{
104 for (auto _ : state) {
106 benchmark::ClobberMemory();
107 }
108}
110
111BENCHMARK_DEFINE_F(RHistAtomic_float, AtomicLoad)(benchmark::State &state)
112{
113 float load;
114 for (auto _ : state) {
116 benchmark::ClobberMemory();
117 }
118}
120
121BENCHMARK_DEFINE_F(RHistAtomic_float, AtomicLoadAcquire)(benchmark::State &state)
122{
123 float load;
124 for (auto _ : state) {
126 benchmark::ClobberMemory();
127 }
128}
130
131BENCHMARK_DEFINE_F(RHistAtomic_float, AtomicStoreRelease)(benchmark::State &state)
132{
133 float store = 1.0f;
134 for (auto _ : state) {
136 benchmark::ClobberMemory();
137 }
138}
140
141struct RHistAtomic_double : public benchmark::Fixture {
142 double fAtomic = 0;
143};
144
145BENCHMARK_DEFINE_F(RHistAtomic_double, Add)(benchmark::State &state)
146{
147 for (auto _ : state) {
148 fAtomic += 1.0;
149 benchmark::ClobberMemory();
150 }
151}
153
154BENCHMARK_DEFINE_F(RHistAtomic_double, AtomicAdd)(benchmark::State &state)
155{
156 for (auto _ : state) {
158 benchmark::ClobberMemory();
159 }
160}
162
163BENCHMARK_DEFINE_F(RHistAtomic_double, AtomicAddRelease)(benchmark::State &state)
164{
165 for (auto _ : state) {
167 benchmark::ClobberMemory();
168 }
169}
171
172BENCHMARK_DEFINE_F(RHistAtomic_double, AtomicLoad)(benchmark::State &state)
173{
174 double load;
175 for (auto _ : state) {
177 benchmark::ClobberMemory();
178 }
179}
181
182BENCHMARK_DEFINE_F(RHistAtomic_double, AtomicLoadAcquire)(benchmark::State &state)
183{
184 double load;
185 for (auto _ : state) {
187 benchmark::ClobberMemory();
188 }
189}
191
192BENCHMARK_DEFINE_F(RHistAtomic_double, AtomicStoreRelease)(benchmark::State &state)
193{
194 double store = 1.0;
195 for (auto _ : state) {
197 benchmark::ClobberMemory();
198 }
199}
201
202struct RBinWithError : public benchmark::Fixture {
204};
205
206BENCHMARK_DEFINE_F(RBinWithError, Inc)(benchmark::State &state)
207{
208 for (auto _ : state) {
209 fBin++;
210 benchmark::ClobberMemory();
211 }
212}
214
215BENCHMARK_DEFINE_F(RBinWithError, AtomicIncRelease)(benchmark::State &state)
216{
217 for (auto _ : state) {
218 fBin.AtomicIncRelease();
219 benchmark::ClobberMemory();
220 }
221}
223
224BENCHMARK_DEFINE_F(RBinWithError, Add)(benchmark::State &state)
225{
226 for (auto _ : state) {
227 fBin += 1.0;
228 benchmark::ClobberMemory();
229 }
230}
232
233BENCHMARK_DEFINE_F(RBinWithError, AtomicAddRelease)(benchmark::State &state)
234{
235 for (auto _ : state) {
236 fBin.AtomicAddRelease(1.0);
237 benchmark::ClobberMemory();
238 }
239}
241
242BENCHMARK_DEFINE_F(RBinWithError, AtomicLoad)(benchmark::State &state)
243{
245 for (auto _ : state) {
246 fBin.AtomicLoad(&load);
247 benchmark::DoNotOptimize(load);
248 }
249}
251
#define _(A, B)
Definition cfortran.h:108
BENCHMARK_DEFINE_F(RHistAtomic_int, Add)(benchmark
BENCHMARK_MAIN()
BENCHMARK_REGISTER_F(RHistAtomic_int, Add)
std::enable_if_t< std::is_arithmetic_v< T > > AtomicLoadAcquire(const T *ptr, T *ret)
std::enable_if_t< std::is_arithmetic_v< T > > AtomicStoreRelease(T *ptr, T *val)
std::enable_if_t< std::is_arithmetic_v< T > > AtomicLoad(const T *ptr, T *ret)
std::enable_if_t< std::is_integral_v< T > > AtomicAdd(T *ptr, T val)
std::enable_if_t< std::is_integral_v< T > > AtomicAddRelease(T *ptr, T val)
TMatrixT< Element > & Add(TMatrixT< Element > &target, Element scalar, const TMatrixT< Element > &source)
Modify addition: target += scalar * source.
ROOT::Experimental::RBinWithError fBin
A special bin content type to compute the bin error in weighted filling.
void AtomicLoad(RBinWithError *ret) const