openmp给出了顺序的不同结果

时间:2014-02-25 14:44:34

标签: fortran openmp

我是openmp的初学者。我试图平行一个简单的循环。但它显然是错误的。 有人可以帮忙吗?

use omp_lib
implicit none
integer ::n=20,it,j
real(8) :: a=0,b=5,s,func,del,sum1,tnm,x
it=2**(n-2)
tnm=it
del=(b-a)/tnm
x=a+.5*del
sum1=0.0

!$omp parallel do reduction(+:sum1)
do j=1,it
  sum1=sum1+func(x)
!  write(*,*)func(x)
  x=x+del
end do
!$omp end parallel do
s=.5*(s+(b-a)*sum1/tnm)
write(*,*)s,sum1,it,del
end

function func(x)
  real(8)::x
  func=x
end function

修改 结果:

并行运行::

$ ifort -openmp trapzd.f90 
$ ./a.out 
  0.976562500000000        102400.000000000           262144
  1.907348632812500E-005

顺序运行

$ ifort  trapzd.f90 
$ ./a.out 
   6.25000000000000        655360.000000000           262144
  1.907348632812500E-005

s,sum1在这两次运行中有所不同

1 个答案:

答案 0 :(得分:3)

我在这里看到三个问题:

  • 函数func
  • 的缺少类型声明
  • s未初始化
  • 变量x
  • 的竞争条件

这对我有用:

program test
  use omp_lib
  implicit none

  integer       :: n=20,it,j
  real(8)       :: a=0,b=5,s,func,del,sum1,tnm,x,x0
  it=2**(n-2)
  tnm=it
  del=(b-a)/tnm
  x=a+.5*del
  sum1=0.0

  x0 = x
  !$omp parallel do reduction(+:sum1)
  do j=1,it
    sum1=sum1+func(x0+j*del)
  !  write(*,*)func(x)
   end do
  !$omp end parallel do

  ! s is uninitialized here - set it to 0
  ! ...probably not what you had in mind
  s = 0.
  s=.5*(s+(b-a)*sum1/tnm)
  write(*,*)s,sum1,it,del

end program

real(8) function func(x)
  real(8)::x
  func=x
end function

使用gfortran编译:

OMP_NUM_THREADS=1 ./a.out 
   6.2500000000000000        655360.00000000000           262144   1.9073486328125000E-005
OMP_NUM_THREADS=6 ./a.out 
   6.2500000000000000        655360.00000000000           262144   1.9073486328125000E-005

使用ifort编译:

OMP_NUM_THREADS=1 ./a.out 
   6.25000000000000        655360.000000000           262144  1.907348632812500E-005
OMP_NUM_THREADS=6 ./a.out 
   6.25000000000000        655360.000000000           262144  1.907348632812500E-005