Browse Source

Don't reset random state in random::init() if already seeded.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
0cd74bf928
2 changed files with 11 additions and 3 deletions
  1. +6
    -2
      include/random.hpp
  2. +5
    -1
      src/random.cpp

+ 6
- 2
include/random.hpp View File

@@ -28,15 +28,19 @@ Example:
double r = normal(rng); double r = normal(rng);
*/ */
struct Xoroshiro128Plus { struct Xoroshiro128Plus {
uint64_t state[2];
uint64_t state[2] = {};


Xoroshiro128Plus(uint64_t s0 = 1, uint64_t s1 = 0) {
void seed(uint64_t s0, uint64_t s1) {
state[0] = s0; state[0] = s0;
state[1] = s1; state[1] = s1;
// A bad seed will give a bad first result, so shift the state // A bad seed will give a bad first result, so shift the state
operator()(); operator()();
} }


bool isSeeded() {
return state[0] || state[1];
}

static uint64_t rotl(uint64_t x, int k) { static uint64_t rotl(uint64_t x, int k) {
return (x << k) | (x >> (64 - k)); return (x << k) | (x >> (64 - k));
} }


+ 5
- 1
src/random.cpp View File

@@ -16,9 +16,13 @@ static std::atomic<uint64_t> threadCounter {0};




void init() { void init() {
// Don't reset state if already seeded
if (rng.isSeeded())
return;

struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
rng = Xoroshiro128Plus(uint64_t(tv.tv_sec) * 1000000 + tv.tv_usec, threadCounter++);
rng.seed(uint64_t(tv.tv_sec) * 1000 * 1000 + tv.tv_usec, threadCounter++);
// Shift state a few times due to low seed entropy // Shift state a few times due to low seed entropy
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
rng(); rng();


Loading…
Cancel
Save