c - 同时使用 rand() 和 rand_r() : is this simple example correct?

标签 c random parallel-processing openmp

我想了解并行随机数生成的正确用法。在查阅了不同的资源后,我写了一个看起来可以工作的简单代码,但如果有人能证实我的理解,那就太好了。

为了指出rand()和rand_r()的区别和关系,我们来求解:

Produce a random integer N, then extract N random numbers in parallel and compute their average.

这是我的建议(检查和自由省略),故意使用小整数:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <omp.h>

int main() {
        /* Initialize and extract an integer via rand() */
        srand(time(NULL));
        int N = rand() % 100;

        /* Storage array */ 
        int *extracted = malloc(sizeof(int) * N);

        /* Initialize N seeds for rand_r, which is completely
         * independent on rand and srand().
         * (QUESTION 1: is it right?)
         * Setting the first as time(NULL), and the others
         * via successive increasing is a good idea (? QUESTION 2)*/
        unsigned int *my_seeds = malloc(sizeof(unsigned int) * N);
        my_seeds[0] = time(NULL);
        for (int i = 1; i < N; ++i) {
                my_seeds[i] = my_seeds[i - 1] + 1;
        }

        /* The seeds for rand_r are ready:
         * extract N random numbers in parallel */
        #pragma omp parallel for
        for (int i = 0; i < N; ++i) {
                extracted[i] = rand_r(my_seeds + i) % 10;
        }

        /* Compute the average: must be done sequentially, QUESTION 3,
         * because of time-sincronization in reading/writing avg */
        double avg = 0;
        for (int i = 0; i < N; ++i) {
                avg += extracted[i];
        }
        avg /= N;
        printf("%d samples, %.2f in average.\n", N, avg);
        return 0;
}

正如我在代码中的评论试图强调的那样,理解如果:

  1. 在这种情况下同时使用 rand 和 rand_r 是正确的;

  2. rand_r 的种子初始化,即变量 my_seeds,没问题;

  3. for 并行化和相关变量使用是安全的。

在阅读了各种在线教程/资源(包括本网站)后,我希望在一个简单易用的示例中总结各种疑惑。

最佳答案

  1. the simultaneous usage of rand and rand_r is in this case correct;

只要:

  • rand不是同时使用的(这在你的代码中是可以的——你只在主线程中调用它一次)
  • rand_r具有相同种子变量的不会同时使用(这在您的代码中是可以的 - 您只需为每个种子变量调用一次)

没有线程安全问题。

  1. the seed's initialization for rand_r, i.e. the variable my_seeds, is fine;

rand_r 的每次(可能)并发使用都有一个单独的种子。只要相同的种子变量不用于并发调用 rand_r(这在您的代码中不会发生),一切都很好。

  1. the for parallelization and related variable usage is safe.

代码中的每个“线程”都有自己的 rand_r 种子变量和自己的结果变量。所以没有并发问题。那个。

旁注:rand_r 已被废弃,randrand_r 均为 relatively low quality prng's .根据您的需要,研究替代 prng 可能是值得的。

关于c - 同时使用 rand() 和 rand_r() : is this simple example correct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58482219/

相关文章:

python - 并行运行单独的进程 - Python

c - 3 个数字中的第二大,使用 if_else

c - 用内存表示查询?

c - 如何修复 Makefile 错误?

c - 将 rand() 用于加密不安全的随机数是否可以接受?

java - 生成一系列值之间的随机 double - Java

c - uint64_t 到数组 - C 语言

batch-file - 如何在cmd批处理文件中创建随机列表

java - 如何在 Ant 中使用并行任务

c++ - OpenMP:一次为线程分配一个迭代