Openmp for循环,种子随机数发生器在哪里?
我读过,为了保证线程安全,它的方便种子并行区域内的RNG
这样的:Openmp for循环,种子随机数发生器在哪里?
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
?
我读过,为了保证线程安全,它的方便,播种RNG并行区域内是这样的:
便利尽管如此,你的技术是不是有效。不管您拨打srand()
的哪个位置,标准rand()
函数都不能成为线程安全的。它依赖于每次调用都会修改的内部静态数据,所以如果您从多个线程调用它(或srand()
)而没有进行某种同步,则会因此创建数据竞争。
一次,POSIX定义了一个函数rand_r()
。如果你有这个,那么它会符合你的目的,但它现在已被标记为过时。在OpenMP中正确使用rand_r()
将涉及在并行区域内部建立私有(OpenMP感知)变量来保存种子。根据每个线程中是否需要相同的随机数序列,在每个线程中以不同或相同方式对其进行初始化。然后将一个指向该变量的指针作为参数传递给rand_r()
。在每次调用之后,您可能想要将返回值或从中派生出来的东西作为新种子。
如果rand_r现在已过时,标准)功能,我应该打电话吗? –
这取决于您正在编程的平台。虽然它已经过时,但不会直接替代'rand_r()',并且在可预见的将来实现实际上不可能将其删除。无论如何,你可以考虑使用它。另外,如果你只需要支持基于glibc的系统,那么还有'random_r()'和一个伴随的'srandom_r()'。 –
因此,您希望每次迭代都创建一组加入其末尾的线程? – StoryTeller
是的,因为外部循环范围可能非常小,所以,假设我有8个线程,如果我把它放在它之前,并且循环范围是(0,3),那么我不会让所有线程都工作,而在这种情况下,因为我的内循环肯定大于8,我相信我得到所有线程工作 –
相关:[从多个线程使用stdlib的rand()](http://stackoverflow.com/q/6161322/2402272)。 –