From 74a75b3a8d155ea155358674d3bf8251658183a5 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 28 Dec 2020 18:18:48 +0100 Subject: Reverted crand.h API back to rename crand_* to stc64_*, and crand_next() -> stc64_rand(). --- benchmarks/crand_benchmark.cpp | 138 +++++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 53 deletions(-) (limited to 'benchmarks/crand_benchmark.cpp') diff --git a/benchmarks/crand_benchmark.cpp b/benchmarks/crand_benchmark.cpp index 78099905..70a3bb45 100644 --- a/benchmarks/crand_benchmark.cpp +++ b/benchmarks/crand_benchmark.cpp @@ -4,15 +4,15 @@ #include static inline uint64_t rotl64(const uint64_t x, const int k) - { return (x << k) | (x >> (64 - k)); } + { return (x << k) | (x >> (64 - k)); } static uint64_t splitmix64_x = 87213627321ull; /* The state can be seeded with any value. */ uint64_t splitmix64(void) { - uint64_t z = (splitmix64_x += 0x9e3779b97f4a7c15); - z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; - z = (z ^ (z >> 27)) * 0x94d049bb133111eb; - return z ^ (z >> 31); + uint64_t z = (splitmix64_x += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); } static void init_state(uint64_t *rng, uint64_t seed) { @@ -23,26 +23,47 @@ static void init_state(uint64_t *rng, uint64_t seed) { /* jsf64 */ static inline uint64_t jsf64(uint64_t *s) { - uint64_t e = s[0] - rotl64(s[1], 7); - s[0] = s[1] ^ rotl64(s[2], 13); - s[1] = s[2] + rotl64(s[3], 37); - s[2] = s[3] + e; - s[3] = e + s[0]; - return s[3]; + uint64_t e = s[0] - rotl64(s[1], 7); + s[0] = s[1] ^ rotl64(s[2], 13); + s[1] = s[2] + rotl64(s[3], 37); + s[2] = s[3] + e; + s[3] = e + s[0]; + return s[3]; } +/* sfc64 */ + +static inline uint64_t sfc64(uint64_t *s) { + uint64_t result = s[0] + s[1] + s[3]++; + s[0] = s[1] ^ (s[1] >> 11); + s[1] = s[2] + (s[2] << 3); + s[2] = rotl64(s[2], 24) + result; + return result; +} + +/* sfc64 with Weyl increment */ +static uint64_t weyl = 1234566789123ull; +static inline uint64_t sfc64w(uint64_t *s) { + uint64_t result = s[0] + s[1] + (s[3] += weyl|1); + s[0] = s[1] ^ (s[1] >> 11); + s[1] = s[2] + (s[2] << 3); + s[2] = rotl64(s[2], 24) + result; + return result; +} + + /* xoshiro256** */ static inline uint64_t xoshiro256starstar(uint64_t* s) { - const uint64_t result = rotl64(s[1] * 5, 7) * 9; - const uint64_t t = s[1] << 17; - s[2] ^= s[0]; - s[3] ^= s[1]; - s[1] ^= s[2]; - s[0] ^= s[3]; - s[2] ^= t; - s[3] = rotl64(s[3], 45); - return result; + const uint64_t result = rotl64(s[1] * 5, 7) * 9; + const uint64_t t = s[1] << 17; + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + s[2] ^= t; + s[3] = rotl64(s[3], 45); + return result; } @@ -63,92 +84,103 @@ using namespace std; int main(void) { - enum {N = 524288000}; + enum {N = 1000000000}; uint64_t* recipient = new uint64_t[N]; - static crand_t rng; + static stc64_t rng; init_state(rng.state, 12345123); + cout << "WARMUP" << endl; + for (size_t i = 0; i < N; i++) + recipient[i] = wyhash64(rng.state); + clock_t beg, end; for (size_t ti = 0; ti < 4; ti++) { + cout << endl << "ROUND " << ti+1 << endl; beg = clock(); for (size_t i = 0; i < N; i++) recipient[i] = wyhash64(rng.state); end = clock(); - cerr << "ROUND " << ti+1 << endl - << "wyhash64:\t" + cout << "wyhash64:\t" << (float(end - beg) / CLOCKS_PER_SEC) - << " s" << endl; - cout << "bogus:" << recipient[312] << endl; + << " s: " << recipient[312] << endl; beg = clock(); for (size_t i = 0; i < N; i++) - recipient[i] = crand_next(&rng); + recipient[i] = sfc64w(rng.state); end = clock(); - cerr << "stc crand:\t" + cout << "sfc64w:\t\t" << (float(end - beg) / CLOCKS_PER_SEC) - << " s" << endl; - cout << "bogus:" << recipient[312] << endl; + << " s: " << recipient[312] << endl; + + beg = clock(); + for (size_t i = 0; i < N; i++) + recipient[i] = stc64_rand(&rng); + end = clock(); + cout << "stc-crand:\t" + << (float(end - beg) / CLOCKS_PER_SEC) + << " s: " << recipient[312] << endl; beg = clock(); for (size_t i = 0; i < N; i++) recipient[i] = xoshiro256starstar(rng.state); end = clock(); - cerr << "xoshiro256**:\t" + cout << "xoshiro256**:\t" << (float(end - beg) / CLOCKS_PER_SEC) - << " s" << endl; - cout << "bogus:" << recipient[312] << endl; + << " s: " << recipient[312] << endl; beg = clock(); for (size_t i = 0; i < N; i++) recipient[i] = lehmer64(rng.state); end = clock(); - cerr << "lehmer64:\t" + cout << "lehmer64:\t" << ((float) end - beg) / CLOCKS_PER_SEC - << " s" << endl; - cout << "bogus:" << recipient[312] << endl; - - + << " s: " << recipient[312] << endl; - cout << endl - << "Next we do random number computations only, doing no work." + cout << "Next we do random number computations only, doing no work." << endl; uint64_t s = 0; beg = clock(); for (size_t i = 0; i < N; i++) s += wyhash64(rng.state); end = clock(); - cerr << "wyhash64:\t" + cout << "wyhash64:\t" + << ((float) end - beg) / CLOCKS_PER_SEC + << " s: " << s << endl; + + s = 0; + beg = clock(); + for (size_t i = 0; i < N; i++) + s += sfc64w(rng.state); + end = clock(); + cout << "sfc64w:\t\t" << ((float) end - beg) / CLOCKS_PER_SEC - << " s" << endl; - cout << "bogus:" << s << endl; + << " s: " << s << endl; s = 0; beg = clock(); for (size_t i = 0; i < N; i++) - s += crand_next(&rng); + s += stc64_rand(&rng); end = clock(); - cerr << "stc crand:\t" + cout << "stc-crand:\t" << ((float) end - beg) / CLOCKS_PER_SEC - << " s" << endl; - cout << "bogus:" << s << endl; + << " s: " << s << endl; s = 0; beg = clock(); for (size_t i = 0; i < N; i++) s += xoshiro256starstar(rng.state); end = clock(); - cerr << "xoshiro256**:\t" + cout << "xoshiro256**:\t" << ((float) end - beg) / CLOCKS_PER_SEC - << " s" << endl; - cout << "bogus:" << s << endl; + << " s: " << s << endl; + s = 0; beg = clock(); for (size_t i = 0; i < N; i++) s += lehmer64(rng.state); end = clock(); - cerr << "lehmer64:\t" + cout << "lehmer64:\t" << ((float) end - beg) / CLOCKS_PER_SEC - << " s" << endl; - cout << "bogus:" << s << endl << endl; + << " s: " << s << endl; } delete[] recipient; return 0; -- cgit v1.2.3