Skip to content

Commit

Permalink
Seed the PRNG with a hashed counter
Browse files Browse the repository at this point in the history
  • Loading branch information
cuviper committed Jun 4, 2018
1 parent b0b6c13 commit ede0a40
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions rayon-core/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use log::Event::*;
use sleep::Sleep;
use std::any::Any;
use std::cell::Cell;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
use std::sync::{Arc, Mutex, Once, ONCE_INIT};
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use std::thread;
use std::mem;
use std::usize;
Expand Down Expand Up @@ -601,7 +604,7 @@ impl WorkerThread {
return None;
}

let start = self.rng.next() as usize % num_threads;
let start = self.rng.next_usize(num_threads);
(start .. num_threads)
.chain(0 .. start)
.filter(|&i| i != self.index)
Expand Down Expand Up @@ -716,12 +719,14 @@ struct XorShift64Star {

impl XorShift64Star {
fn new() -> Self {
// Any non-zero seed will do -- this uses a stack address, which should be unique since
// we're only calling this once from each new thread. The address is also shift-XORed to
// give us some high bits even on 32-bit platforms.
let base = 0;
let addr = &base as *const _ as u64;
let seed = addr ^ (addr << 32);
// Any non-zero seed will do -- this uses the hash of a global counter.
let mut seed = 0;
while seed == 0 {
let mut hasher = DefaultHasher::new();
static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
hasher.write_usize(COUNTER.fetch_add(1, Ordering::Relaxed));
seed = hasher.finish();
}

XorShift64Star {
state: Cell::new(seed),
Expand All @@ -737,4 +742,9 @@ impl XorShift64Star {
self.state.set(x);
x.wrapping_mul(0x2545_f491_4f6c_dd1d)
}

/// Return a value from [0,n).
fn next_usize(&self, n: usize) -> usize {
(self.next() % n as u64) as usize
}
}

0 comments on commit ede0a40

Please # to comment.