program ompPrime
#ifdef _OPENMP
include 'omp_lib.h' !needed for OMP_GET_NUM_THREADS()
#endif
integer :: start = 1
integer :: end = 100000000
integer :: number_of_primes = 0
integer :: number_of_41primes = 0
integer :: number_of_43primes = 0
integer index, factor, limit, nthr
double precision st, fin
real rindex, rlimit
logical prime, print_primes
CALL CPU_TIME(st)
print_primes = .false.
nthr = 1 ! assume just one thread
print *, ' Range to check for Primes:',start,end
#ifdef _OPENMP
!$omp parallel
!$omp single
nthr = OMP_GET_NUM_THREADS()
print *, ' We are using',nthr,' thread(s)'
!$omp end single!
!$omp do private(factor, limit, prime) &
SCHEDULE(dynamic,10) &
reduction(+:number_of_primes,number_of_41primes,number_of_43primes)
#else
print *, ' We are using',nthr,' thread(s)'
#endif
do index = start, end, 2 !workshared loop
limit = int(sqrt(real(index)))
prime = .true. ! assume number is prime
factor = 3
do
if(prime .and. factor .le. limit) then
if(mod(index,factor) .eq. 0) then
prime = .false.
endif
factor = factor + 2
else
exit ! we can jump out of non-workshared loop
endif
enddo
if(prime) then
if(print_primes) then
print *, index, ' is prime'
endif
number_of_primes = number_of_primes + 1
if(mod(index,4) .eq. 1) then
number_of_41primes = number_of_41primes + 1
endif
if(mod(index,4) .eq. 3) then
number_of_43primes = number_of_43primes + 1
endif
endif ! if(prime)
enddo
!$omp end do
!$omp end parallel
CALL CPU_TIME(fin)
print '("Time = ",1P6E12.4," seconds.")',fin-st
print *,number_of_primes
read *,number_of_primes
end program ompPrime
OpenMPI для Windows
Хотел бы распаралеллить свою программу.
Но не могу никак разобраться как (и откуда) установить MPI для Windows.
Буду рад любой помощи. Спасибо!
Используйте: MPICH for Windows, MS-MPI или Intel MPI.
Решил попробовать на персональном компьютере (4 ядра) библиотеку OpenMP.
Нашел прямо в Intel Visual Studio - пример (для OpenMP), который ищет простые числа от 1 до N перебором.
Запустил. По диспетчеру задач - во время работы программы - используются все 4 ядра и загрузка ЦП 100%. Время счета ~ 1 минуты.
Но вот незадача. Если убрать параллелизм и оставить только сам алгоритм перебора, то судя по диспетчеру задач занято только одно ядро. Загрузка ЦП ~ 25%, но время счета не изменяется (!!!) и опять порядка ~ 1 минуты.
В чем может быть дело?
Код программы прилагаю:
Код:
Компилировал так
Код:
gfortran -cpp -fopenmp -o ompPrime ompPrime.f90
Код:
./ompPrime
Range to check for Primes: 1 100000000
We are using 4 thread(s)
Time = 1.4891E+02
5761455
OMP_NUM_THREADS=2 ./ompPrime
Range to check for Primes: 1 100000000
We are using 2 thread(s)
Time = 9.4435E+01
5761455
OMP_NUM_THREADS=1 ./ompPrime
Range to check for Primes: 1 100000000
We are using 1 thread(s)
Time = 8.8408E+01
5761455
Range to check for Primes: 1 100000000
We are using 4 thread(s)
Time = 1.4891E+02
5761455
OMP_NUM_THREADS=2 ./ompPrime
Range to check for Primes: 1 100000000
We are using 2 thread(s)
Time = 9.4435E+01
5761455
OMP_NUM_THREADS=1 ./ompPrime
Range to check for Primes: 1 100000000
We are using 1 thread(s)
Time = 8.8408E+01
5761455
Действительно, при работе в 4 потока, где-то в 3.5 раза быстрее.