Intereting Posts

OpenMP-распараллеливание вычисления pi либо медленное, либо неправильное

У меня возникают проблемы с параллелизмом моего метода monte carlo для вычисления pi. Вот параллельный цикл for:

#pragma omp parallel for private(i,x,y) schedule(static) reduction(+:count) for (i = 0; i < points; i++) { x = rand()/(RAND_MAX+1.0)*2 - 1.0; y = rand()/(RAND_MAX+1.0)*2 - 1.0; // Check if point lies in circle if(x*x + y*y < 1.0) { count++; } } 

Проблема в том, что она недооценивает pi, если я использую schedule(static) и медленнее, чем последовательная реализация, если я использую schedule(dynamic) . Что я делаю неправильно? Я пробовал другие способы исправить это (например: Использование OpenMP для вычисления значения PI ), но оно все еще намного медленнее, чем последовательная реализация.

заранее спасибо

Предполагая, что вы используете функцию rand библиотеки C, эта функция не является реентерабельной или streamобезопасной. POSIX предоставляет функцию rand_r , но (для цитирования документации glibc):

POSIX.1 расширил стандартные функции C для поддержки воспроизводимых случайных чисел в многопоточных программах. Однако расширение плохо спроектировано и непригодно для серьезной работы.

В частности, семя должно быть беззнаковым int, который не имеет достаточного количества бит для хорошего PRNG. Они рекомендуют использовать функции случайных чисел SVID, из которых nrand48_r – это, вероятно, то, что вы ищете.

Кроме того, вы можете использовать другую библиотеку.

Одна вещь, которую вы должны учитывать при параллельном выполнении таких вещей, заключается в том, что могут быть разные ошибки округления, вызванные различными способами расчета.

Пример:

((A+B) + (C+D)) где (A+B) и (C+D) будут вычисляться параллельно, могут варьироваться от последовательного подхода (((A+B) + C) + D) .