omp 屏障相当于 Fortran 中的 omp end 并行吗

Alp*_*F20 5 fortran openmp

我的问题是关于同步线程。基本上,如果我有一段OpenMP代码Fortran,每个线程都在做某事。我认为同步它们有两种可能性(让某个变量在每个线程中具有相同的值)。

  1. 添加!$OMP BARRIER
  2. 添加!$OMP END PARALLEL。如有必要,请稍后添加!$OMP PARALLEL!$OMP END PARALLEL阻止。

选项 1) 和 2) 等效吗?我看到一些关于barrier嵌套线程omp 屏障嵌套线程的问题 到目前为止,我对更简单的扫描更感兴趣Fortran。例如,对于下面的代码,如果我使用barrier,则两个 if (sum > 500) then条件似乎表现相同,至少在gfortran.

PROGRAM test
USE OMP_LIB

integer :: numthreads, i, sum



numthreads = 2
sum = 0

call omp_set_num_threads(numthreads)

!$OMP PARALLEL


  if (OMP_GET_THREAD_NUM() == 0) then
    write (*,*) 'a'
    
    do i = 1, 30
      write (*,*) sum
      sum = sum +  i
    end do 

    !write (*,*) 'sum', sum
  else if  (OMP_GET_THREAD_NUM() == 1) then
    write (*,*) 'b'
    do i = 1, 15
      write (*,*) sum
      sum = sum +  i
    end do  
    
    !write (*,*) 'sum', sum    
  end if  

!$OMP BARRIER

  if (sum > 500) then
    write (*,*) 'sum v1'
  else
    write (*,*) 'not yet v1'
  end if

!$OMP END PARALLEL

 
  if (sum > 500) then
    write (*,*) 'sum v2', sum
  else
    write (*,*) 'not yet v2', sum
  end if
 

END

Run Code Online (Sandbox Code Playgroud)

我关心的是,对于代码

blah1 
!$OMP PARALLEL 
!$OMP END PARALLEL
blah2
Run Code Online (Sandbox Code Playgroud)

如果计算机将执行为blah1-> omp-> blah2。如果变量(例如,sum示例代码中的)已blah2omp块中完全求值,我不需要担心某些线程是否omp会更快,计算条目的一部分(例如,sum在问题中),然后继续对于部分if 中的条件blah2,会导致一些意想不到的结果。

Ian*_*ush 4

不,它们根本不等同。

!$omp end parallel我们稍微思考一下并行性在 OpenMP 中是如何工作的。在程序开始时,您只有一个所谓的主线程可用。这种情况一直持续到您到达并行区域为止,在该并行区域中您有多个可用线程、主线程和(可能)许多其他线程。在 Fortran 中,并行区域由!$omp parallel指令启动。它由!$omp end parallel指令关闭,之后您的代码就可以使用主线程,直到启动另一个并行区域。因此!$omp end parallel简单地标记了并行区域的结束。

在并行区域内,许多 OpenMP 指令开始产生影响。其中之一是!$omp barrier要求给定线程在代码中的该点等待,直到所有线程都到达该点(当使用嵌套并行性之类的东西时,请仔细选择“all”值 - 请参阅https:// /www.openmp.org/spec-html/5.0/openmpsu90.html了解更多详情)。!$omp barrier与划定平行区域无关。因此,在使用它之后,所有线程仍然可供使用,并且在并行区域之外它不会产生任何影响。

下面的小代码可能有助于说明问题

ijb@ijb-Latitude-5410:~/work/stack$ cat omp_bar.f90
Program omp_bar

  !$ Use omp_lib, Only : omp_get_num_threads, omp_in_parallel

  Implicit None

  Integer n_th
  
  !$omp parallel default( none ) private( n_th )
  n_th = 1
  !$ n_th = omp_get_num_threads()
  Write( *, * ) 'Hello at 1 on ', n_th, ' threads. ', &
       'Are we in a parallel region ?', omp_in_parallel()
  !$omp barrier
  Write( *, * ) 'Hello at 2', omp_in_parallel()
  !$omp end parallel

  Write( *, * ) 'Hello at 3', omp_in_parallel()

End Program omp_bar
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ijb@ijb-Latitude-5410:~/work/stack$ gfortran -fopenmp -std=f2008 -Wall -Wextra -fcheck=all -O -g omp_bar.f90 
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
 Hello at 1 on            2  threads. Are we in a parallel region ? T
 Hello at 1 on            2  threads. Are we in a parallel region ? T
 Hello at 2 T
 Hello at 2 T
 Hello at 3 F
Run Code Online (Sandbox Code Playgroud)

[是的,我知道屏障不能保证同步输出顺序,我在这里很幸运]