#ifndef rng_h #define rng_h #include #include #include class romutrio { public: explicit romutrio(uint64_t seed) : x(seed), y(seed + 0x9e3779b97f4a7c15ull), z(seed + 0x3243f6a8885a308dull) { } uint64_t operator()() { uint64_t xp = x, yp = y, zp = z; x = 15241094284759029579ull * zp; y = yp - xp; y = std::rotl(y, 12); z = zp - yp; z = std::rotl(z, 44); return xp; } private: uint64_t x, y, z; }; class shishua { public: explicit shishua(uint64_t seed) : x(0x9E3779B97F4A7C15ull ^ seed), y(0xF39CC0605CEDC834ull ^ seed), z(0x1082276BF3A27251ull ^ seed), w(0xF86C6A11D0C18E95ull) { } uint64_t operator()() { uint64_t u0 = x >> 1; uint64_t u1 = y >> 3; uint64_t t0 = y; uint64_t t1 = z; x = t0 + u0; y = t1 + u1; z = w + (x >> 1); w = x + (y >> 3); return u0 ^ t1; } private: uint64_t x, y, z, w; }; class shishua_avx2 { public: explicit shishua_avx2(uint64_t seed) { state[0] = _mm256_set_epi64x( 0xF86C6A11D0C18E95ull ^ seed, 0x1082276BF3A27251ull, 0xF39CC0605CEDC834ull ^ seed, 0x9E3779B97F4A7C15ull); state[1] = _mm256_set_epi64x( 0xF86C6A11D0C18E95ull, 0x1082276BF3A27251ull ^ seed, 0xF39CC0605CEDC834ull, 0x9E3779B97F4A7C15ull ^ seed); counter = _mm256_set_epi64x(7, 5, 3, 1); } uint64_t operator()() { __m256i u0 = _mm256_srli_epi64(state[0], 1); __m256i u1 = _mm256_srli_epi64(state[1], 3); __m256i shu0 = _mm256_set_epi32(4, 3, 2, 1, 0, 7, 6, 5); __m256i shu1 = _mm256_set_epi32(2, 1, 0, 7, 6, 5, 4, 3); __m256i t0 = _mm256_permutevar8x32_epi32(state[0], shu0); __m256i t1 = _mm256_permutevar8x32_epi32(state[1], shu1); state[1] = _mm256_add_epi64(state[1], counter); counter = _mm256_add_epi64(counter, _mm256_set_epi64x(7, 5, 3, 1)); state[0] = _mm256_add_epi64(t0, u0); state[1] = _mm256_add_epi64(t1, u1); return _mm256_extract_epi64(_mm256_xor_si256(u0, t1), 0); } private: __m256i state[2], counter; }; class xorshift32 { public: explicit xorshift32(uint32_t seed): state(seed) {} uint32_t operator()() { state ^= state << 13; state ^= state >> 17; state ^= state << 5; return state; } private: uint32_t state; }; #endif // rng_h