2

我面临的问题概述如下:

module k
  integer :: l,m
end module k

program p4
  use k
  integer :: i,j,omp_get_thread_num,cr

  i = 2
  j = 3

  !$omp parallel num_threads(2) shared(l,m) private(i,j,cr)
  cr = omp_get_thread_num()
  if (cr == 0) goto 1111
  call sub1(i)
  write(*,*) l
  goto 2222
1111 call sub2(j)
  write(*,*) m
2222 continue
  !$omp end parallel
end program p4

subroutine sub1(a)
  use k
  integer :: a

  l = a**2
  write(*,*) 'entered sub1'
end subroutine sub1

subroutine sub2(b)
  use k
  integer :: b

  m = b**2
  write(*,*) 'entered sub2'
end subroutine sub2

我试图并行化一个串行,(并行化后看起来如上所写)。我希望基本上相同的操作执行两次。所以理想情况下,我希望输出是

entered sub1
4
enterer sub2
9

但输出是

entered sub2
           0
entered sub1
   923239424

我是并行编程的新手,(我的实际问题是我所概述的更复杂的版本)。任何人都可以指出错误并提出改进建议。谢谢

4

1 回答 1

8

OpenMPprivate变量没有被赋予初始值,因此对sub1和的调用sub2都是使用 和 的随机值进行ij。您(可能)正在寻找的是firstprivate

!$omp parallel num_threads(2) shared(l,m) private(cr) firstprivate(i,j)
...
!$omp end parallel

firstprivate使用主线程中的相应变量在进入并行区域时所具有的值初始化每个私有副本。

顺便说一句,在 Fortran 90 及更高版本中实现IF/THEN/ELSE/ENDIFwithIF/GOTO/CONTINUE被许多人认为是一种糟糕的编程风格。您应该改用 OpenMP 部分:

!$omp parallel sections num_threads(2) shared(l,m) private(cr) firstprivate(i,j)
  !$omp section
  call sub1(i)
  write(*,*) l
  !$omp section
  call sub2(j)
  write(*,*) m
!$omp end parallel sections
于 2013-09-30T11:18:30.583 回答