简体   繁体   English

如何让每个线程在C ++ 11中使用自己的RNG

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

I'm using the new random number generators in in C++11. 我在C ++ 11中使用新的随机数生成器。 Although there are varying opinions, from this thread it seems that the majority believe they are not thread safe. 尽管存在不同的意见,但从这个主题看来,大多数人认为它们不是线程安全的。 As a consequence, I would like to make a program, where each thread uses its own RNG. 因此,我想制作一个程序,每个线程使用自己的RNG。

An example is given in the related discussion of how to accomplish this with OpenMP: 在如何使用OpenMP实现此目的的相关讨论中给出了一个示例:

#include <random>
#include <iostream>
#include <time.h>
#include "omp.h"

using namespace std;



int main()
{
    unsigned long long app = 0;
    {
        //mt19937_64 engine((omp_get_thread_num() + 1)); //USE FOR MULTITHREADING
        mt19937_64 engine; //USE FOR SINGLE THREAD
        uniform_real_distribution<double> zeroToOne(0.0, 1.0);

        //#pragma omp parallel for reduction(+:app) //USE FOR MULTITHREADING
        for (unsigned long long i = 0; i < 2000000000; i++)
        {
            if(zeroToOne(engine) < 0.5) app++;
        }
    }
    cout << app << endl;
    return 0;
}

When I run the multi-threaded and single-threaded version of this program and keep track of the time, they take the same amount of time to finish after execution. 当我运行该程序的多线程和单线程版本并跟踪时间时,执行后需要相同的时间才能完成。 Also, app does not have the same size in the two cases, but I suspect that is merely because of the different seeds. 此外, app在两种情况下的大小不同,但我怀疑这仅仅是因为种子不同。

Question : Does the provided example correctly show how to force each thread to use its own RNG? 问题 :提供的示例是否正确显示了如何强制每个线程使用自己的RNG? If not, can I see an example of how this is done, or get a reference to some place where they explain how to achieve this? 如果没有,我可以看一个如何完成这个的例子,或者参考一些他们解释如何实现这个目的的地方?

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)). 您应该锁定单个引擎或为每个线程创建一个引擎(使用不同的种子(请注意e4e5f4关于创建并行MT引擎的答案))。 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 . 在OpenMP的情况下,您可以轻松地在每个线程中存储一个引擎,并通过位于0和omp_get_num_threads()–1之间的omp_get_thread_num()结果检索它。

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 我建议像一些久经考验的解决这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM