std :: random_device的线程安全性

The*_*dus 17 c++ random openmp c++11

我有一些看起来有点像这样的代码:

std::random_device rd;

#pragma omp parallel
{
    std::mt19937 gen(rd());
    #pragma omp for
    for(int i=0; i < N; i++)
    {
        /* Do stuff with random numbers from gen() */
    }
}
Run Code Online (Sandbox Code Playgroud)

我有几个问题:

  • std::random_device线程安全的?也就是说当几个线程立刻调用它时,它会做一些无用的事情吗?
  • 这通常是个好主意吗?我应该担心重叠的随机数流吗?
  • 有没有更好的方法来实现我想要的(每个线程中的独立随机数流 - 我现在不太担心可重复性)?

如果它对std::random_device我主要在Windows上运行的工作有任何影响,尽管我希望代码在Linux和OSX上同样运行良好.

Bro*_*olf 6

并行使用随机设备并不是一个好主意。即使它被阻塞,您也可能不会遇到重叠随机数流的问题,但您会添加一个额外的同步点。

您应该设置与要启动的线程一样多的随机数引擎 (RNE) omp_get_num_threads()。创建 RNE 的 std::vector 并将它们播种到程序的顺序部分中。对于播种,您可以使用随机设备和std::seed_seq

然后在每个线程中使用与线程号 关联的 RNE omp_get_thread_num()

切勿使用随机设备生成随机数,它很慢并且通常不会生成均匀分布的随机数!

根据您需要的随机数的质量,您可以使用预定义的随机数生成器之一。如果您正在进行蒙特卡罗模拟或密码学,请特别小心您选择的算法。

您可以在https://en.cppreference.com/w/cpp/numeric/random找到很多有关随机引擎的有用信息 。