21 #include <initializer_list>
25 #include <type_traits>
28 #include "absl/base/macros.h"
29 #include "absl/meta/type_traits.h"
30 #include "absl/random/bernoulli_distribution.h"
31 #include "absl/random/beta_distribution.h"
32 #include "absl/random/exponential_distribution.h"
33 #include "absl/random/gaussian_distribution.h"
34 #include "absl/random/internal/fast_uniform_bits.h"
35 #include "absl/random/internal/randen_engine.h"
36 #include "absl/random/log_uniform_int_distribution.h"
37 #include "absl/random/poisson_distribution.h"
38 #include "absl/random/random.h"
39 #include "absl/random/uniform_int_distribution.h"
40 #include "absl/random/uniform_real_distribution.h"
41 #include "absl/random/zipf_distribution.h"
42 #include "benchmark/benchmark.h"
48 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
49 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6,
50 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
51 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
52 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A18FF, 0x5664526C, 0xC2B19EE1,
53 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
54 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
55 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
56 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0x13198A2E, 0x03707344,
61 class PrecompiledSeedSeq {
65 PrecompiledSeedSeq() {}
67 template <
typename Iterator>
71 PrecompiledSeedSeq(std::initializer_list<T> il) {}
73 template <
typename OutIterator>
75 static size_t idx = 0;
86 template <
typename OutIterator>
87 void param(OutIterator
out)
const {
102 template <
typename Engine,
typename SSeq = PrecompiledSeedSeq>
111 template <
typename Engine,
typename SSeq = PrecompiledSeedSeq>
118 template <
typename Engine,
typename SSeq>
121 auto rng = make_engine<Engine, SSeq>();
126 template <
typename Engine>
130 auto rng = make_engine<Engine>();
137 template <
typename Engine>
142 std::vector<value_type>
v(64);
143 auto rng = make_engine<Engine>();
144 while (
state.KeepRunningBatch(64)) {
149 template <
typename Engine,
size_t elems>
152 std::vector<uint32_t>
v(elems);
153 while (
state.KeepRunningBatch(elems)) {
154 auto rng = make_engine<Engine>();
159 template <
typename Engine,
size_t elems>
162 std::vector<uint32_t>
v(elems);
163 auto rng = make_engine<Engine>();
164 while (
state.KeepRunningBatch(elems)) {
169 template <
typename Engine,
typename Dist,
typename...
Args>
172 auto rng = make_engine<Engine>();
173 Dist dis{std::forward<Args>(
args)...};
181 template <
typename Engine,
typename Dist>
186 BM_Dist<Engine, Dist>(
state, kMin, kMax);
189 template <
typename Engine,
typename Dist>
194 BM_Dist<Engine, Dist>(
state, kMin, kMax);
197 template <
typename Engine,
typename Dist,
int A>
199 volatile double a =
static_cast<double>(
A) / 1000000;
200 BM_Dist<Engine, Dist>(
state,
a);
203 template <
typename Engine,
typename Dist,
int A,
int B>
208 BM_Dist<Engine, Dist>(
state,
a,
b);
211 template <
typename Engine,
typename Dist,
int A>
215 BM_Dist<Engine, Dist>(
state,
a);
218 template <
typename Engine,
typename Dist,
int A = 100>
220 volatile double a =
static_cast<double>(
A) / 100;
221 BM_Dist<Engine, Dist>(
state,
a);
224 template <
typename Engine,
typename Dist,
int Q = 2,
int V = 1>
227 volatile double q =
Q;
228 volatile double v = V;
232 template <
typename Engine,
typename Dist>
235 auto rng = make_engine<Engine>();
250 #define BM_BASIC(Engine) \
251 BENCHMARK_TEMPLATE(BM_Construct, Engine, PrecompiledSeedSeq); \
252 BENCHMARK_TEMPLATE(BM_Construct, Engine, std::seed_seq); \
253 BENCHMARK_TEMPLATE(BM_Direct, Engine); \
254 BENCHMARK_TEMPLATE(BM_Shuffle, Engine, 10); \
255 BENCHMARK_TEMPLATE(BM_Shuffle, Engine, 100); \
256 BENCHMARK_TEMPLATE(BM_Shuffle, Engine, 1000); \
257 BENCHMARK_TEMPLATE(BM_ShuffleReuse, Engine, 100); \
258 BENCHMARK_TEMPLATE(BM_ShuffleReuse, Engine, 1000); \
259 BENCHMARK_TEMPLATE(BM_Dist, Engine, \
260 absl::random_internal::FastUniformBits<uint32_t>); \
261 BENCHMARK_TEMPLATE(BM_Dist, Engine, \
262 absl::random_internal::FastUniformBits<uint64_t>); \
263 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::uniform_int_distribution<int32_t>); \
264 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::uniform_int_distribution<int64_t>); \
265 BENCHMARK_TEMPLATE(BM_Dist, Engine, \
266 absl::uniform_int_distribution<int32_t>); \
267 BENCHMARK_TEMPLATE(BM_Dist, Engine, \
268 absl::uniform_int_distribution<int64_t>); \
269 BENCHMARK_TEMPLATE(BM_Large, Engine, \
270 std::uniform_int_distribution<int32_t>); \
271 BENCHMARK_TEMPLATE(BM_Large, Engine, \
272 std::uniform_int_distribution<int64_t>); \
273 BENCHMARK_TEMPLATE(BM_Large, Engine, \
274 absl::uniform_int_distribution<int32_t>); \
275 BENCHMARK_TEMPLATE(BM_Large, Engine, \
276 absl::uniform_int_distribution<int64_t>); \
277 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::uniform_real_distribution<float>); \
278 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::uniform_real_distribution<double>); \
279 BENCHMARK_TEMPLATE(BM_Dist, Engine, absl::uniform_real_distribution<float>); \
280 BENCHMARK_TEMPLATE(BM_Dist, Engine, absl::uniform_real_distribution<double>)
282 #define BM_COPY(Engine) BENCHMARK_TEMPLATE(BM_Generate, Engine)
284 #define BM_THREAD(Engine) \
285 BENCHMARK_TEMPLATE(BM_Thread, Engine, \
286 absl::uniform_int_distribution<int64_t>) \
288 BENCHMARK_TEMPLATE(BM_Thread, Engine, \
289 absl::uniform_real_distribution<double>) \
291 BENCHMARK_TEMPLATE(BM_Shuffle, Engine, 100)->ThreadPerCpu(); \
292 BENCHMARK_TEMPLATE(BM_Shuffle, Engine, 1000)->ThreadPerCpu(); \
293 BENCHMARK_TEMPLATE(BM_ShuffleReuse, Engine, 100)->ThreadPerCpu(); \
294 BENCHMARK_TEMPLATE(BM_ShuffleReuse, Engine, 1000)->ThreadPerCpu();
296 #define BM_EXTENDED(Engine) \
298 BENCHMARK_TEMPLATE(BM_Small, Engine, \
299 std::uniform_int_distribution<int32_t>); \
300 BENCHMARK_TEMPLATE(BM_Small, Engine, \
301 std::uniform_int_distribution<int64_t>); \
302 BENCHMARK_TEMPLATE(BM_Small, Engine, \
303 absl::uniform_int_distribution<int32_t>); \
304 BENCHMARK_TEMPLATE(BM_Small, Engine, \
305 absl::uniform_int_distribution<int64_t>); \
306 BENCHMARK_TEMPLATE(BM_Small, Engine, std::uniform_real_distribution<float>); \
307 BENCHMARK_TEMPLATE(BM_Small, Engine, \
308 std::uniform_real_distribution<double>); \
309 BENCHMARK_TEMPLATE(BM_Small, Engine, \
310 absl::uniform_real_distribution<float>); \
311 BENCHMARK_TEMPLATE(BM_Small, Engine, \
312 absl::uniform_real_distribution<double>); \
314 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::normal_distribution<double>); \
315 BENCHMARK_TEMPLATE(BM_Dist, Engine, absl::gaussian_distribution<double>); \
316 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::exponential_distribution<double>); \
317 BENCHMARK_TEMPLATE(BM_Dist, Engine, absl::exponential_distribution<double>); \
318 BENCHMARK_TEMPLATE(BM_Poisson, Engine, std::poisson_distribution<int64_t>, \
320 BENCHMARK_TEMPLATE(BM_Poisson, Engine, absl::poisson_distribution<int64_t>, \
322 BENCHMARK_TEMPLATE(BM_Poisson, Engine, std::poisson_distribution<int64_t>, \
324 BENCHMARK_TEMPLATE(BM_Poisson, Engine, absl::poisson_distribution<int64_t>, \
326 BENCHMARK_TEMPLATE(BM_Poisson, Engine, std::poisson_distribution<int64_t>, \
328 BENCHMARK_TEMPLATE(BM_Poisson, Engine, absl::poisson_distribution<int64_t>, \
330 BENCHMARK_TEMPLATE(BM_Dist, Engine, \
331 absl::log_uniform_int_distribution<int32_t>); \
332 BENCHMARK_TEMPLATE(BM_Dist, Engine, \
333 absl::log_uniform_int_distribution<int64_t>); \
334 BENCHMARK_TEMPLATE(BM_Dist, Engine, std::geometric_distribution<int64_t>); \
335 BENCHMARK_TEMPLATE(BM_Zipf, Engine, absl::zipf_distribution<uint64_t>); \
336 BENCHMARK_TEMPLATE(BM_Zipf, Engine, absl::zipf_distribution<uint64_t>, 2, \
338 BENCHMARK_TEMPLATE(BM_Bernoulli, Engine, std::bernoulli_distribution, \
340 BENCHMARK_TEMPLATE(BM_Bernoulli, Engine, absl::bernoulli_distribution, \
342 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<double>, 65, \
344 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<double>, 99, \
346 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<double>, 150, \
348 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<double>, 410, \
350 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<float>, 65, 41); \
351 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<float>, 99, \
353 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<float>, 150, \
355 BENCHMARK_TEMPLATE(BM_Beta, Engine, absl::beta_distribution<float>, 410, \
357 BENCHMARK_TEMPLATE(BM_Gamma, Engine, std::gamma_distribution<float>, 199); \
358 BENCHMARK_TEMPLATE(BM_Gamma, Engine, std::gamma_distribution<double>, 199);