none
parallel_for and generator of random numbers for it

    Question

  • Hi,

    it is for VC++ 14 (VS 2017 Community under windows 7 SP1.First, some pseudo code:

    std::vector<MyObjects> vObjects;
    
    Concurrency::parallel_for(0, vObjects.size(), 
        [] () 
        { 
            Generate a random number rn;
            MyObject myObject = vObjects[rn];; 
            Foo(myObject);
        });

    I know that the random number generators from C++ <random> are not thread-safe.

    Usually people recommend using a separate generator for every thread.

    There is also "concurrent random number generation in C++17" http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0010r0.pdf) that uses a vector for 4 threads:

    using given_engine = mt19937;
    std::vector<Normal_Rnd<given_engine>>N(4);

    It uses mt19937::discard() to get non-overlapping random sequences from independent generators.

    All is supposed to work just fine if you know what thread you are in at every iteration of the loop

    Is there some way to know what thread is executing in the particular iteration of the loop or it is better to manually divide the operation between parallel tasks?

    Or, may be Microsoft already solved this Problem?

    Thank you.

     


    • Edited by Geoyar Wednesday, February 7, 2018 10:19 PM
    Wednesday, February 7, 2018 10:17 PM

All replies

  • Maybe like this:

    Concurrency::parallel_for_each( vObjects.begin(), vObjects.end(), []( MyObject & o )
    {
       double random_number = distr( gen );
       // . . .
    } );

     

    where:

    auto rdf = []() -> random_device & { static thread_local random_device rd; return rd; };
    thread_local mt19937 gen( rdf()( ) );
    thread_local normal_distribution<> distr;
    


    • Edited by Viorel_MVP Thursday, February 8, 2018 6:28 PM
    Thursday, February 8, 2018 6:26 PM
  • Thank you for replay.

    I may be wrong, but for me it seems that all mt19937 gens in threads are seeded with the equal seeds. And what will happen when gen(rdf()) is called the second time in the same thread? (I just do not know thread_local well.)

    What I want is to use thread_local rt19937 in every thread covering the sequence of states as if it was one generator. For example, if I need 12000 random numbers, and I have 4 CPU cores, I will seed all 4 generators with the same seed, and discard 3000 states  of the second generator, 6000  states of the third etc., as offered in tech note  'Adding a subsection for concurrent random number generation in C++17.'  (It is more complicated, but the idea is that.)

    Friday, February 9, 2018 11:49 PM