how to make each thread use its own RNG in C++11

a 夏天 提交于 2019-12-02 20:56:08

You must no share instances of random engine between multiple threads. You should either lock a single engine or create one engine for each thread (with different seed (please note the answer of e4e5f4 regarding creation of parallel MT engines)). In case of OpenMP you can easily store one engine per thread in a vector and retrieve it by result of omp_get_thread_num() which lies between 0 and omp_get_num_threads()–1.

class RNG
{
public:
    typedef std::mt19937 Engine;
    typedef std::uniform_real_distribution<double> Distribution;

    RNG() : engines(), distribution(0.0, 1.0)
    {
        int threads = std::max(1, omp_get_max_threads());
        for(int seed = 0; seed < threads; ++seed)
        {
            engines.push_back(Engine(seed));
        }
    }

    double operator()()
    {
        int id = omp_get_thread_num();
        return distribution(engines[id]);
    }

    std::vector<Engine> engines;
    Distribution distribution;
};

int main()
{
     RNG rand;
     unsigned long app = 0;

     #pragma omp parallel for reduction(+:app)
     for (unsigned long long i = 0; i < 2000000000; i++)
     {
         if(rand() < 0.5) app++;
     }
}

I would refrain from using random seeding. It might end up with overlapping streams. This will eventually affect the final statistic.

I would suggest some tried and tested solution like this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!