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

What is the safe way to generate random number with a known seed using OpenMP?

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

在 monte Carlo 模拟的上下文中,您可以使用 rand_r. From this SO Thread 可以阅读:

I think you're looking for rand_r(), which explicitly takes the current RNG state as a parameter. Then each thread should have it's own copy of seed data (whether you want each thread to start off with the same seed or different ones depends on what you're doing, here you want them to be different or you'd get the same row again and again).

这实际上是在 中的 Monte Carlo 模拟的并行实现中使用的函数,实际上产生了良好的结果。该答案的代码:

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):

Might be worth noting that rand_r only has an int for state (i.e. likely 32bits), so the entire space could get exhausted pretty quickly during a large MC run. 128 bits of state seems more reasonable, which would necessitate some other algorithm (e.g. PCG-64 or xoroshiro128)

只需从初始种子开始,为每个线程计算种子,并使用具有该线程特定种子的良好 RNG。

为了获得好的 RNG,您可能需要阅读有关 PCG 的内容。