首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用rand()和rand_r():这个简单的示例正确吗?

使用rand()和rand_r():这个简单的示例正确吗?
EN

Stack Overflow用户
提问于 2019-10-21 08:09:03
回答 1查看 978关注 0票数 2

我试图理解并行随机数生成的正确用法。在查阅了不同的资源之后,我编写了一段简单的代码,看起来很有效,但是如果有人能证实我的理解,那就太好了。

为了指出rand()和rand_r()之间的区别和关系,我们来解决以下问题:

生成一个随机整数N,然后并行提取N个随机数并计算它们的平均值。

这是我的建议(检查和免费省略),小整数故意:

代码语言:javascript
复制
#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. 用于并行化和相关的变量使用是安全的。

我希望在一个单一的,简单的,现成的例子总结各种怀疑,在阅读了各种教程/来源在线(包括这个网站)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-21 08:55:57

  1. rand和rand_r的同时使用在本例中是正确的;

只要:

  • rand不是并发使用的(在您的代码中这是ok的--您只在主thread)
  • rand_r中调用它一次,同时不使用相同的种子变量(在您的代码中这是好的--您只对每个种子变量调用它一次)

线程安全没有问题。

  1. 种子对rand_r的初始化,即变量my_seeds,很好;

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

用于并行化和相关变量使用的

  1. 是安全的。

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

附带注意:rand_r已经过时,randrand_r都是relatively low quality prng's。根据你的需要,调查另一种选择可能是值得的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58482219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档