使用 OpenMP 使用已知种子生成随机数的安全方法是什么?

问题描述 投票:0回答:3

我正在寻找一种能够在输入种子已知的情况下与 OpenMP 并行安全生成随机数的方法。我搜索并最终找到了 OMPRNG。还有另一种方法可以使用我可以手动编写代码的包吗? 另外,我想提一下,我需要这些随机数来进行 monto Carlo 积分。

multithreading random parallel-processing openmp
3个回答
3
投票

在蒙特卡洛模拟的上下文中,您可以使用rand_r。从这个SO Thread可以读到:

我认为您正在寻找 rand_r(),它明确采用 当前 RNG 状态作为参数。那么每个线程应该有它的 自己的种子数据副本(是否希望每个线程以 相同的种子或不同的种子取决于你在做什么,在这里你 希望它们不同,否则你会一次又一次地得到同一行)。

这实际上是在这个 SO Thread 中并行实现蒙特卡洛模拟所使用的函数,实际上产生了良好的结果。该答案的代码:

int main(void)
{
    double start = omp_get_wtime();
    long points = 1000000000; //....................................... INPUT AVOIDED
    long m = 0;
    unsigned long HAUSNUMERO = 1;
    double DIV1byMAXbyMAX = 1. / RAND_MAX / RAND_MAX;

    int threads = get_nprocs();
    omp_set_num_threads(threads);
    #pragma omp parallel reduction (+: m )
    {
        unsigned int aThreadSpecificSEED_x = HAUSNUMERO + 1 + omp_get_thread_num();
        unsigned int aThreadSpecificSEED_y = HAUSNUMERO - 1 + omp_get_thread_num();
        #pragma omp for nowait
        for(long i = 0; i < points; i++)
        {
            double x = rand_r( &aThreadSpecificSEED_x );
            double y = rand_r( &aThreadSpecificSEED_y );
            m += (1  >= ( x * x + y * y ) * DIV1byMAXbyMAX);
        }
    }
    double end = omp_get_wtime();
    printf("%f\n",end-start);
    printf("Pi is roughly %lf\n", (double) 4*m / (double) points);
}

引用评论部分(Sam Manson):

可能值得注意的是 rand_r 只有一个 int 表示状态(即 可能是 32 位),所以整个空间可能很快就会耗尽 在大型 MC 运行期间。 128 位状态似乎更合理,其中 需要一些其他算法(例如 PCG-64 或 xoroshiro128)


1
投票

只需从初始种子开始,计算每个线程的种子,然后将良好的 RNG 与该线程特定的种子结合使用。

对于优秀的 RNG,您可能需要阅读有关 PCG 的信息。


0
投票

只要放这条线

int random() {
  srand(time(NULL));
  return 1 + rand() % 10;
}
© www.soinside.com 2019 - 2024. All rights reserved.