我想了解并行随机数生成的正确用法。在查阅了不同的资源后,我写了一个看起来可以工作的简单代码,但如果有人能证实我的理解,那就太好了。
为了指出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;
}
正如我在代码中的评论试图强调的那样,理解如果:
在这种情况下同时使用 rand 和 rand_r 是正确的;
rand_r 的种子初始化,即变量 my_seeds,没问题;
for 并行化和相关变量使用是安全的。
在阅读了各种在线教程/资源(包括本网站)后,我希望在一个简单易用的示例中总结各种疑惑。
最佳答案
- the simultaneous usage of rand and rand_r is in this case correct;
只要:
没有线程安全问题。
- the seed's initialization for rand_r, i.e. the variable my_seeds, is fine;
rand_r
的每次(可能)并发使用都有一个单独的种子。只要相同的种子变量不用于并发调用 rand_r
(这在您的代码中不会发生),一切都很好。
- the for parallelization and related variable usage is safe.
代码中的每个“线程”都有自己的 rand_r
种子变量和自己的结果变量。所以没有并发问题。那个。
旁注:rand_r
已被废弃,rand
和 rand_r
均为 relatively low quality prng's .根据您的需要,研究替代 prng 可能是值得的。
关于c - 同时使用 rand() 和 rand_r() : is this simple example correct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58482219/