homer512

meshtool rand_generator fix

Oct 6th, 2025 (edited)
3,735
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 2.03 KB | Source Code | 0 0
  1. diff --git a/utils/rand_generator.h b/utils/rand_generator.h
  2. index 45e09d0..eb7f41d 100644
  3. --- a/utils/rand_generator.h
  4. +++ b/utils/rand_generator.h
  5. @@ -2,6 +2,7 @@
  6.  #define _RAND_GENERATOR_H
  7.  
  8.  #include <stdlib.h>
  9. +#include <random>
  10.  #include <vector>
  11.  
  12.  #ifdef OPENMP
  13. @@ -17,8 +18,23 @@ class rand_generator
  14.    public:
  15.    rand_generator(size_t rsize) : _rands(rsize), _ridx(0)
  16.    {
  17. +    /*
  18. +     * We use a single seed value that is incremented per thread.
  19. +     * See here for motivation:
  20. +     * https://www.johndcook.com/blog/2016/01/29/random-number-generator-seed-mistakes/
  21. +     */
  22. +    static unsigned global_seed = std::random_device()();
  23. +    unsigned thread_seed;
  24. +#   pragma omp atomic relaxed capture
  25. +    thread_seed = global_seed++;
  26. +    /*
  27. +     * Consider using a better random number generator. This one should resemble
  28. +     * drand48(), which was used previously
  29. +     */
  30. +    std::minstd_rand rng(thread_seed);
  31. +    std::uniform_real_distribution<float> distr;
  32.      for(size_t i=0; i<_rands.size(); i++)
  33. -      _rands[i] = drand48();
  34. +      _rands[i] = distr(rng);
  35.    }
  36.  
  37.    rand_generator() : rand_generator(4*1024*1024)
  38. @@ -32,7 +48,11 @@ class rand_generator
  39.  };
  40.  
  41.  class rand_generator_state {
  42. -  mt_vector<rand_generator> global_rands;
  43. +  /*
  44. +   * use std::vector instead of mt_vector because we have to avoid calling
  45. +   * new rand_generator[N] which would invoke the costly default constructor
  46. +   */
  47. +  std::vector<rand_generator> global_rands;
  48.  
  49.    public:
  50.    rand_generator_state() {
  51. @@ -41,8 +61,13 @@ class rand_generator_state {
  52.      {
  53.        int tid      = omp_get_thread_num();
  54.        int nthreads = omp_get_num_threads();
  55. -      if (tid == 0)
  56. -        global_rands.resize(nthreads);
  57. +      /*
  58. +       * Create a vector of empty generators, then let each thread
  59. +       * initialize its own
  60. +       */
  61. +#     pragma omp single
  62. +      global_rands.resize(nthreads, rand_generator(0));
  63. +      global_rands[tid] = rand_generator();
  64.      }
  65.  #else
  66.      global_rands.resize(1);
  67.  
Advertisement