Мне нужна помощь для распараллеливания вычисления pi методом monte carlo с помощью openmp с помощью генератора случайных чисел, который не является потокобезопасным.Корректные прагмы OpenMP для pi monte carlo в C с генератором случайных чисел, не зависящим от потока
Первый: This SO нитка не помогла мне.
Моя собственная попытка - это следующие операторы #pragma omp. Я думал, что i, x и y vars должны быть инициализированы каждым потоком и должны быть закрытыми. z ist сумма всех попаданий в круге, поэтому ее следует суммировать после предполагаемого барриера после цикла for.
Подумайте, основная проблема ist статическое состояние var генератора случайных чисел. Я сделал критический раздел, где вызываются функции, так что только один поток за время может его выполнить. Но решения Pi не масштабируются с более высокими значениями.
Примечание: Я не должен использовать другой RNG, но его все в порядке, чтобы сделать небольшие изменения на нем.
int main (int argc, char *argv[]) {
int i, z = 0, threads = 8, iters = 100000;
double x,y, pi;
#pragma omp parallel firstprivate(i,x,y) reduction(+:z) num_threads(threads)
for (i=0; i<iters; ++i) {
#pragma omp critical
{
x = rng_doub(1.0);
y = rng_doub(1.0);
}
if ((x*x+y*y) <= 1.0)
z++;
}
pi = ((double) z/(double) (iters*threads))*4.0;
printf("Pi: %lf\n", pi);;
return 0;
}
Это ГСЧ фактически включаемый файл, но я не уверен, если я создаю файл заголовка правильно, я включил его в другой файл программы, так что у меня есть только один файл .c.
#define RNG_MOD 741025
int rng_int(void) {
static int state = 0;
return (state = (1366 * state + 150889) % RNG_MOD);
}
double rng_doub(double range) {
return ((double) rng_int())/(double) ((RNG_MOD - 1)/range);
}
Я также попытался сделать статическое int state глобальным, но это не меняет моего результата, возможно, я сделал это неправильно. Так что, пожалуйста, не могли бы вы помочь мне внести правильные изменения? Большое спасибо!
Не могли бы вы прояснить смысл слов: «Но решения Pi не масштабируются с более высокими значениями». _ Помимо того, что критический раздел сериализует ваши потоки, и вы не получите никакой скорости, код выглядит корректно для меня. –
Да, конечно. Я имею в виду, что рассчитанный pi должен быть ближе к реальному значению pi, если я буду работать с большим количеством итераций. Но с этим генератором случайных чисел я вообще не вижу этого поведения. И доцент говорит, что из-за нити-unsafty из штата var. Я должен установить его глобальным и использовать один или несколько правильных операторов #pragma omp для его обработки. Но я пробовал много комбинаций и ничего не меняет. Не знаю, если я принимаю состояние var global, а не как статическое или нет? И критически важно на этом месте? Нужно состояние для совместного использования()? Или лучше threadprivate (состояние)? Я уже много пробовал. –
Я обновил свой ответ, используя вашу случайную функцию. –