主题:用fortran与OpenMP并行成功了
我的配置是IVF9.1,v studio2005,Openmp2.5,进入代码界面后要设置属性---fortran--language--process--OpenMp Dirctives为Generate parallel code
这个并行的问题,我研究了很长时间,首先你要明确以下几点才能并行:
1 你的计算机是双核以上的
2 计算机的系统是64位的如XP64位(原因是现在的CPU多是采用64位架构,因此系统也要是64位的0
3 你所用的IVF有64位组件,也异是在安装时会有64MT。。。(在安装的过程中可以看到这个组件的安装)
4 在IVF中要配置参数,project--(×) properties-fortran——language——process openMP Directives ——generate parallel code(Qopenmp)
5 你的程序可以并行,即程序中有可以并行的地方,前后没有逻辑关系
基本上把这几点弄懂了,差不多可以进行简单的并行计算了
program main
!*****************************************************************************80
!
!! MAIN is the main program for TEST_OMP.
!
! Discussion:
!
! TEST_OMP estimates the value of PI.
!
! This program uses Open MP parallelization directives.
!
! It should run properly whether parallelization is used or not.
!
! However, the parallel version computes the sum in a different
! order than the serial version; some of the quantities added are
! quite small, and so this will affect the accuracy of the results.
!
! Modified:
!
! 29 January 2003
!
! Author:
!
! John Burkardt
!
! A FORTRAN 90 module may be available:
!
! use omp_lib
!
! A FORTRAN 77 include file may be available:
!
! include 'omp_lib.h'
!
implicit none
integer, parameter :: r4_logn_max = 9
integer id
integer nthreads
integer omp_get_num_procs
integer omp_get_num_threads
integer omp_get_thread_num
call timestamp ( )
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'TEST_OMP'
write ( *, '(a)' ) ' FORTRAN90 version'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' Estimate the value of PI by summing a series.'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' This program includes Open MP directives, which'
write ( *, '(a)' ) ' may be used to run the program in parallel.'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' The number of processors available:'
write ( *, '(a,i8)' ) ' OMP_GET_NUM_PROCS () = ', omp_get_num_procs ( )
nthreads = 4
write ( *, '(a)' ) ' '
write ( *, '(a,i8,a)' ) ' Call OMP_SET_NUM_THREADS, and request ', &
nthreads, ' threads.'
call omp_set_num_threads ( nthreads )
!
! Note that the call to OMP_GET_NUM_THREADS will always return 1
! if called outside a parallel region!
!
!$OMP parallel private ( id )
id = omp_get_thread_num ( )
write ( *, '(a,i3)' ) ' This is process ', id
if ( id == 0 ) then
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' Calling OMP_GET_NUM_THREADS inside a '
write ( *, '(a)' ) ' parallel region, we get the number of'
write ( *, '(a,i3)' ) ' threads is ', omp_get_num_threads ( )
write ( *, '(a)' ) ' '
end if
!$OMP end parallel
call r4_test ( r4_logn_max )
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'TEST_OMP'
write ( *, '(a)' ) ' Normal end of execution.'
write ( *, '(a)' ) ' '
call timestamp ( )
stop
end
subroutine r4_test ( logn_max )
!*****************************************************************************80
!
!! R4_TEST estimates the value of PI using single precision.
!
! Discussion:
!
! PI is estimated using N terms. N is increased from 10^2 to 10^LOGN_MAX.
! The calculation is repeated using both sequential and Open MP enabled code.
! Wall clock time is measured by calling SYSTEM_CLOCK.
!
! Modified:
!
! 06 January 2003
!
! Author:
!
! John Burkardt
!
implicit none
integer clock_max
integer clock_rate
integer clock_start
integer clock_stop
real error
real estimate
integer logn
integer logn_max
character ( len = 3 ) mode
integer n
real r4_pi
real time
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'R4_TEST:'
write ( *, '(a)' ) ' Estimate the value of PI,'
write ( *, '(a)' ) ' using single precision arithmetic.'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' N = number of terms computed and added;'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' ESTIMATE = the computed estimate of PI;'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' ERROR = ( the computed estimate - PI );'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' TIME = elapsed wall clock time;'
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' Note that you can''t increase N forever, because:'
write ( *, '(a)' ) ' A) ROUNDOFF starts to be a problem, and'
write ( *, '(a)' ) ' B) maximum integer size is a problem.'
write ( *, '(a)' ) ' '
write ( *, '(a,i12)' ) ' The maximum integer:' , huge ( n )
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' '
write ( *, '(a)' ) ' N Mode Estimate Error Time'
write ( *, '(a)' ) ' '
n = 1
do logn = 2, logn_max
mode = 'OMP'
call system_clock ( clock_start, clock_rate, clock_max )
call r4_pi_est_omp ( n, estimate )
call system_clock ( clock_stop, clock_rate, clock_max )
time = real ( clock_stop - clock_start ) / real ( clock_rate )
error = abs ( estimate - r4_pi ( ) )
write ( *, '( i12, 2x, a3, 2x, f14.10, 2x, g14.6, 2x, g14.6 )' ) &
n, mode, estimate, error, time
n = n * 10
end do
return
end
subroutine r4_pi_est_omp ( n, estimate )
!*****************************************************************************80
!
!! R4_PI_EST_OMP estimates the value of PI, using Open MP.
!
! Discussion:
!
! The calculation is based on the formula for the indefinite integral:
!
! Integral 1 / ( 1 + X**2 ) dx = Arctan ( X )
!
! Hence, the definite integral
!
! Integral ( 0 <= X <= 1 ) 1 / ( 1 + X**2 ) dx
! = Arctan ( 1 ) - Arctan ( 0 )
! = PI / 4.
!
! A standard way to approximate an integral uses the midpoint rule.
! If we create N equally spaced intervals of width 1/N, then the
! midpoint of the I-th interval is
!
! X(I) = (2*I-1)/(2*N).
!
! The approximation for the integral is then:
!
! Sum ( 1 <= I <= N ) (1/N) * 1 / ( 1 + X(I)**2 )
!
! In order to compute PI, we multiply this by 4; we also can pull out
! the factor of 1/N, so that the formula you see in the program looks like:
!
! ( 4 / N ) * Sum ( 1 <= I <= N ) 1 / ( 1 + X(I)**2 )
!
! Until roundoff becomes an issue, greater accuracy can be achieved by
! increasing the value of N.
!
! Modified:
!
! 06 January 2003
!
! Author:
!
! John Burkardt
!
! Parameters:
!
! Input, integer N, the number of terms to add up.
!
! Output, real ESTIMATE, the estimated value of pi.
!
implicit none
real h
real estimate
integer i
integer n
real sum2
real x
h = 1.0E+00 / real ( 2 * n )
sum2 = 0.0E+00
!
!$OMP parallel do private(x) shared(h) reduction(+: sum2)
!
do i = 1, n
x = h * real ( 2 * i - 1 )
sum2 = sum2 + 1.0E+00 / ( 1.0E+00 + x**2 )
end do
estimate = 4.0E+00 * sum2 / real ( n )
return
end
function r4_pi ( )
!*****************************************************************************80
!
!! R4_PI returns the value of pi.
!
! Modified:
!
! 02 February 2000
!
! Author:
!
! John Burkardt
!
! Parameters:
!
! Output, real R4_PI, the value of pi.
!
implicit none
real r4_pi
r4_pi = 3.14159265358979323846264338327950288419716939937510E+00
return
end
subroutine timestamp ( )
!*****************************************************************************80
!
!! TIMESTAMP prints the current YMDHMS date as a time stamp.
!
! Example:
!
! May 31 2001 9:45:54.872 AM
!
! Modified:
!
! 31 May 2001
!
! Author:
!
! John Burkardt
!
! Parameters:
!
! None
!
implicit none
character ( len = 8 ) ampm
integer d
character ( len = 8 ) date
integer h
integer m
integer mm
character ( len = 9 ), parameter, dimension(12) :: month = (/ &
'January ', 'February ', 'March ', 'April ', &
'May ', 'June ', 'July ', 'August ', &
'September', 'October ', 'November ', 'December ' /)
integer n
integer s
character ( len = 10 ) time
integer values(8)
integer y
character ( len = 5 ) zone
call date_and_time ( date, time, zone, values )
y = values(1)
m = values(2)
d = values(3)
h = values(5)
n = values(6)
s = values(7)
mm = values(8)
if ( h < 12 ) then
ampm = 'AM'
else if ( h == 12 ) then
if ( n == 0 .and. s == 0 ) then
ampm = 'Noon'
else
ampm = 'PM'
end if
else
h = h - 12
if ( h < 12 ) then
ampm = 'PM'
else if ( h == 12 ) then
if ( n == 0 .and. s == 0 ) then
ampm = 'Midnight'
else
ampm = 'AM'
end if
end if
end if
write ( *, '(a,1x,i2,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) &
trim ( month(m) ), d, y, h, ':', n, ':', s, '.', mm, trim ( ampm )
return
end