Openmp for循环,在哪里播种随机数生成器?

时间:2017-03-07 16:23:22

标签: c random thread-safety openmp

我已经读过,为了确保线程安全,可以方便地将RNG种植到并行区域内,如下所示:

int seedbase = 392872;

#pragma omp parallel 
{
   srand(omp_get_thread_id * seedbase);
   #pragma omp for
   ....
}

但是如果我的并行化部分在另一个循环中呢?如果我有这样的情况:

int seedbase = 392872;
for(int i=0; i<100; ++i)
{
    #pragma omp parallel 
    {
      srand(omp_get_thread_id * seedbase);
      #pragma omp for
      ....
    }
}

我应该在哪里初始化RNG

1 个答案:

答案 0 :(得分:1)

  

我已经读过,为了确保线程安全,可以方便地将RNG播种到并行区域内,如下所示:

尽管方便​​,但您的技术并非有效。无论您在何处调用srand(),标准rand()函数都不能成为线程安全的。它依赖于在每次调用时修改的内部静态数据,因此如果您在没有某种同步的情况下从多个线程调用它(或srand()),那么您就会创建数据竞争。

POSIX一度定义了一个函数rand_r()。如果你有它那么它将满足你的目的,但它现在已被标记为过时。正确使用rand_r()与OpenMP将涉及在并行区域内建立一个私有(OpenMP sense)变量来保存种子。在每个线程中以不同或相同的方式初始化它,具体取决于您是否希望在每个线程中使用相同的随机数序列。然后,将指向该变量的指针作为参数传递给rand_r()。在每次调用之后,您可能希望将返回值或从其派生的内容作为新种子。