0

I have a function object for parallelizing a for_each() algorithm using Thread Building Blocks,

The function object uses a random number generator RND whose operator method () generates a random number.

Problem: I need a random number number generator to 1) initialize only once in the function object 2) should be threadsafe and 3) can be provided same seed so that same results could be obtained.

I dont know much about generating thread safe random number generators in function objects as such. I tried using my own random generator class (using engine, distribution and generators) (using boost libraries) but I need something simple such as erand() ? or something like that for which we dont need to do write separate code.

struct func {
 public:
  func() {  } 
  func(int t_) : t(t_) {  }  

 template <typename house_t>
 void operator()(house_t  house)  const  { 

   if ( RND() ) 
   {  //do something with the house } 

 } //operator

 private:
   int t;
 };


 //Parallel for_each
 tbb::parallel_for_each( house.begin(), house.end(), func(t) ); 

Please suggest

pugs
  • 155
  • 1
  • 8
  • I don't think what you're asking for is possible since there is no guarantee in what order the items in the parallel_for_each will be executed. To make this deterministic with a parallel_for_each I think you need to serially generate your array of random values and then pass them to the parallel_for_each as pre-generated inputs. If you were manually parallelizing you could have a separate seed / RNG state for each 'chunk' of the array but I don't know of a way to do that in tbb. – mattnewport Aug 05 '14 at 23:30
  • @mattnewport: Okay, lets forget the same seed for now. what if I use a erand48(xsubi) and initialize it in the functor, and then provide it to TBB parallel_for_each? – pugs Aug 05 '14 at 23:34
  • 2
    I'm not familiar with erand48() but most PRNGs are not thread safe by default so you will have to manually lock around calls to your PRNG. A better general alternative for generating PRNGs across multiple threads is to maintain separate PRNG state for each thread but again I'm not sure if that's possible with a tbb parallel_for_each, you could do it with the combiner class in Microsoft's PPL I think, perhaps there's something equivalent in tbb. – mattnewport Aug 05 '14 at 23:46
  • I still think your best bet in this case is to pre-generate your array of random numbers and pass it to the paralle_for_each as input as that will solve both your determinism problem and your synchronization problem. If the random number generation is a significant fraction of the runtime of your function however then you won't see as much benefit from parallelizing as you might hope. – mattnewport Aug 05 '14 at 23:48
  • You might consider the technique described in http://www.thesalmons.org/john/random123/papers/random123sc11.pdf . That would work in TBB. Cilk supports deterministic random generation in this kind of context, but the mechanism relies on Cilk's fork-join straitjacket (https://software.intel.com/en-us/blogs/2013/03/08/new-contributed-code-for-cilk-plus-dotmix-a-deterministic-parallel-random-number) – Arch D. Robison Aug 07 '14 at 22:24

0 Answers0