如何使每个线程在C ++ 11中使用自己的RNG [英] how to make each thread use its own RNG in C++11

查看:113
本文介绍了如何使每个线程在C ++ 11中使用自己的RNG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++ 11中使用新的随机数生成器。虽然有不同的意见,从这个线程,似乎大多数相信他们不是线程安全的。因此,我想制作一个程序,其中每个线程都使用自己的RNG。

I'm using the new random number generators in in 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.

一个例子在相关的讨论中给出如何使用OpenMP :

An example is given in the related discussion of how to accomplish this with 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;
}



当我运行这个程序的多线程和单线程版本,跟踪时间,他们采取相同的时间量完成后执行。此外, app 在这两种情况下大小不一样,但我怀疑这只是因为种子不同。

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.

问题:提供的示例是否正确显示如何强制每个线程使用自己的RNG?如果没有,我可以看到一个例子,如何做,或得到一个地方,他们解释如何实现这一点的参考。

Question: Does the provided example correctly show how to force each thread to use its own 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?

推荐答案

您不能在多个线程之间共享随机引擎的实例。你应该锁定单个引擎或为每个线程创建一个引擎(具有不同的种子(请注意e4e5f4关于创建并行MT引擎的答案))。在OpenMP的情况下,你可以轻松地在一个向量中存储一个引擎,并通过 omp_get_thread_num()的结果检索它,它在0和 omp_get_num_threads )-1

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++;
     }
}

这篇关于如何使每个线程在C ++ 11中使用自己的RNG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆