我的问题是关于同步线程。基本上,如果我有一段OpenMP代码Fortran,每个线程都在做某事。我认为同步它们有两种可能性(让某个变量在每个线程中具有相同的值)。
!$OMP BARRIER!$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示例代码中的)已blah2在omp块中完全求值,我不需要担心某些线程是否omp会更快,计算条目的一部分(例如,sum在问题中),然后继续对于部分if 中的条件blah2,会导致一些意想不到的结果。
不,它们根本不等同。
让!$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)
[是的,我知道屏障不能保证同步输出顺序,我在这里很幸运]
| 归档时间: |
|
| 查看次数: |
410 次 |
| 最近记录: |