如何使用OpenMP在C代码中生成介于0和1之间的均匀分布的随机数? [英] How to generate uniformly distributed random numbers between 0 and 1 in a C code using OpenMP?

查看:310
本文介绍了如何使用OpenMP在C代码中生成介于0和1之间的均匀分布的随机数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个OpenMP代码,其中每个线程将在0到1之间均匀分布的随机数的大数组上工作.每个线程需要具有不同且独立的随​​机数分布.另外,每次调用代码时,随机数分布都需要不同.这就是我现在正在使用的.这是否总是保证每个线程都有自己的/不同的随机数序列?每次调用代码时,序列会有所不同吗?正确的做法是什么?以下代码使每个线程生成5个样本,但在实际运行中,它将达到数百万个量级.

I am trying to write an OpenMP code in which each thread will work on big arrays of uniformly distributed random numbers between 0 and 1. Each thread needs to have different and independent random number distributions. In addition, the random number distributions need to be different every time the code is called. This is what I am using right now. Does this always guarantee each thread has its own/different random number sequences? Will the sequences be different every time the code is called? What is the correct way of doing this? The following code has each thread generating 5 samples but in an actual run it will be order of millions.

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

int main(int argc, char* argv[])
{
    int numthreads,i;
    #pragma omp parallel private(i)
    {
        int id;
        id=omp_get_thread_num();
        if(id==0) numthreads = omp_get_num_threads();
        printf("thread %d \n",id);
        srand(time(0)^omp_get_thread_num());
        for (i=0; i<5; i++)
        {
            printf("thread %d: %d %.6f \n",id,i,(double)rand()/(double)RAND_MAX);
        }
    }
    return 0;
}

推荐答案

您没有提到正在使用的操作系统,但是如果是Linux或POSIX兼容系统,则有 getentropy() ,BSD具有 clock_gettime() 是一个很好的来源.

You don't mention what OS you're using, but if it's Linux or a POSIX compliant system, there's erand48() for thread-safe generation of random numbers uniformly distributed in the range [0.0, 1.0). It uses a 48-bit seed that's passed as an argument. Generating the initial seed can be done in a number of ways. OpenBSD and Linux have getentropy(), BSDs have arc4random_buf(), you can read from the /dev/urandom special file on many OSes, or do something like you're currently using with time, pid, etc. I'd suggest a higher resolution timer than time(), though - clock_gettime() is a good source.

一个例子:

#include <errno.h>
#include <fcntl.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
#pragma omp parallel for
  for (int i = 0; i < 4; i++) {
    unsigned short xi[3]; // PRNG state variable

#if 0
    // OpenBSD 5.6+/Linux kernel 3.17+ and glibc 2.25+
    if (getentropy(xi, sizeof xi) < 0) {
      perror("getentropy");
      exit(EXIT_FAILURE);
    }
#else
    // Read from /dev/urandom
    int fd = open("/dev/urandom", O_RDONLY);
    if (fd < 0) {
      perror("open /dev/urandom");
      exit(EXIT_FAILURE);
    }
    if (read(fd, xi, sizeof xi) != sizeof xi) {
      perror("read");
      exit(EXIT_FAILURE);
    }
    close(fd);
#endif

    for (int n = 0; n < 4; n++) {
      printf("Thread %d random number %f\n", omp_get_thread_num(), erand48(xi));
    }
  }

  return 0;
}

这篇关于如何使用OpenMP在C代码中生成介于0和1之间的均匀分布的随机数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆