jeudi 4 février 2021

Reproducible results with parallel_for and random numbers possible?

I have code which involves some heavy computations so I use the parallel_for loop in Visual Studio C++. This works fine and the code runs much faster in comparison with a normal for loop.

My problem is that I want reproducible results but the computations involve random numbers. I can use a fixed seed but this does seem to work when using a parallel_for loop.

Example code:

#include <iostream>
#include <random>
#include <ppl.h>

#define USE_PAR 1

std::mutex m;
double x_min = 1.0e300;

double draw()
{
    int seed = 1;
    std::uniform_real_distribution<double> d(-1.0, 1.0);
    static std::mt19937 mt(seed);
    return d(mt);
}

void expensive_function()
{
    double x;
    for (volatile int i = 0; i < 1000; ++i)
        x = draw();
    std::lock_guard<std::mutex> lock(m);
    if (x < x_min)
        x_min = x;
}

void test()
{
#if USE_PAR
    concurrency::parallel_for(size_t(0), size_t(10), [&](size_t i) { expensive_function(); });
#else
    for (size_t i = 0; i < 10; ++i) { expensive_function(); }
#endif
    std::cout << x_min << "\n";
}

int main()
{
    for (int i = 0; i < 10; ++i) test();
}

When I use a normal for loop instead of parallel_for (USE_PAR = 0), I reproducibly get the same output every time I run the program:

-0.935609
-0.952062
-0.952062
-0.952062
-0.952062
-0.952062
-0.988225
-0.988225
-0.988225
-0.99249

But with the parallel_for loop (USE_PAR = 1), I get a different result everytime. For example the first time:

-0.733511
-0.733511
-0.855412
-0.855412
-0.93122
-0.93122
-0.93122
-0.987444
-0.987444
-0.987444

And then the second time:

-0.90946
-0.997749
-0.997749
-0.997749
-0.997749
-0.997749
-0.997749
-0.997749
-0.997749
-0.997749

Is it possible to have both? Good performance with parallel_for and reproducible results even if random numbers are used?




Aucun commentaire:

Enregistrer un commentaire