我有一个教科书示例,演示了通过参数修复数据范围。我想知道为什么在下面的代码片段中作者使用 COMMON 块来定义两个变量,istart和iend,** 应该是每个线程私有的?具有 COMMON 属性的变量的“共享”属性与作者将 **istart和iend指定为私有的意图是否冲突?还是我们应该简单地删除公共块?
作者说:“我们使用一个名为 bounds 的通用块,其中包含 istart 和 iend,本质上包含主程序和子程序中使用的值。” 我想知道公共属性是否会被每个线程的调用子例程继承并干扰istart和iend应该承担的“私有”属性。
李
program main
...
common /bounds/ istart,iend
integer :: iarray(10000),N
N=10000
...
!$omp parallel private(iam,nthreads,chunk), &
!$omp& private(istart,iend)
nthreads=omp_get_num_threads()
iam = omp_getthread_num()
chunk=(N+nthreads-1)/nthreads
istart=iam*chunk+1
iend=min((iam+1)*chunk,N)
call work(iarray,istart,iend)
!$omp end parallel
end program main
subroutine work(iarray,istart,iend)
...
integer :: iarray(10000)
do i=istart,iend
iarray(i)=i*i
endddo
end subroutine work
在另一个示例中,作者出于相同目的编写了以下代码片段。在这种情况下,我应该在主程序和子程序中都保留公共块,对吗?
program main
...
common /bounds/ istart, iend
!$omp threadprivate(/bounds/)
integer iarray(10000)
N = 10000
!$omp parallel private(iam, nthreads, chunk)
nthreads = omp_get_num_threads()
iam = omp_get_thread_num()
chunk = (N + nthreads – 1)/nthreads
istart = iam * chunk + 1
iend = min((iam + 1) * chunk, N)
call work(iarray)
!$omp end parallel
end program main
subroutine work(iarray)
...
common /bounds/ istart, iend
!$omp threadprivate(/bounds/)
integer iarray(10000)
do i = istart, iend
iarray(i) = i * i
enddo
end subroutine work
如果我喜欢以现代方式传递变量istart和iend,我是否正确地进行了以下修订(这对我来说看起来有点奇怪,因为 threadprivate 子句的参数不是公共块的名称):
program main
use model
...
!$omp threadprivate(istart,iend)
integer iarray(10000)
N = 10000
!$omp parallel private(iam, nthreads, chunk)
nthreads = omp_get_num_threads()
iam = omp_get_thread_num()
chunk = (N + nthreads – 1)/nthreads
istart = iam * chunk + 1
iend = min((iam + 1) * chunk, N)
call work(iarray)
!$omp end parallel
end program main
module model
integer :: istart,iend
contains
subroutine work(iarray)
...
!$omp threadprivate(istart,iend)
integer iarray(10000)
do i = istart, iend
iarray(i) = i * i
enddo
end subroutine work
end module model