Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/utils/rand_generator.h b/utils/rand_generator.h
- index 45e09d0..eb7f41d 100644
- --- a/utils/rand_generator.h
- +++ b/utils/rand_generator.h
- @@ -2,6 +2,7 @@
- #define _RAND_GENERATOR_H
- #include <stdlib.h>
- +#include <random>
- #include <vector>
- #ifdef OPENMP
- @@ -17,8 +18,23 @@ class rand_generator
- public:
- rand_generator(size_t rsize) : _rands(rsize), _ridx(0)
- {
- + /*
- + * We use a single seed value that is incremented per thread.
- + * See here for motivation:
- + * https://www.johndcook.com/blog/2016/01/29/random-number-generator-seed-mistakes/
- + */
- + static unsigned global_seed = std::random_device()();
- + unsigned thread_seed;
- +# pragma omp atomic relaxed capture
- + thread_seed = global_seed++;
- + /*
- + * Consider using a better random number generator. This one should resemble
- + * drand48(), which was used previously
- + */
- + std::minstd_rand rng(thread_seed);
- + std::uniform_real_distribution<float> distr;
- for(size_t i=0; i<_rands.size(); i++)
- - _rands[i] = drand48();
- + _rands[i] = distr(rng);
- }
- rand_generator() : rand_generator(4*1024*1024)
- @@ -32,7 +48,11 @@ class rand_generator
- };
- class rand_generator_state {
- - mt_vector<rand_generator> global_rands;
- + /*
- + * use std::vector instead of mt_vector because we have to avoid calling
- + * new rand_generator[N] which would invoke the costly default constructor
- + */
- + std::vector<rand_generator> global_rands;
- public:
- rand_generator_state() {
- @@ -41,8 +61,13 @@ class rand_generator_state {
- {
- int tid = omp_get_thread_num();
- int nthreads = omp_get_num_threads();
- - if (tid == 0)
- - global_rands.resize(nthreads);
- + /*
- + * Create a vector of empty generators, then let each thread
- + * initialize its own
- + */
- +# pragma omp single
- + global_rands.resize(nthreads, rand_generator(0));
- + global_rands[tid] = rand_generator();
- }
- #else
- global_rands.resize(1);
Advertisement