Я пытаюсь понять правильное использование параллельной генерации случайных чисел. Посоветовавшись с различными ресурсами, я написал простой код, который, кажется, работает, но было бы неплохо, если бы кто-то смог подтвердить мое понимание.
Ради того, чтобы указать на разницу и отношения между rand () и rand_r(), давайте решим:
Создайте случайное целое число N, затем извлеките N случайных чисел параллельно и вычислите их среднее значение.
Это мое предложение (проверка и бесплатнаяпропущено), целые маленькие числа:
#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, в порядке;
дляраспараллеливание и использование связанных переменных безопасны.
Я надеюсь обобщить различные сомнения в одном простом, готовом к использованию примере, прочитав различные учебные пособия / источникиine (этот веб-сайт включен).