Parallel processing 将变量直接传递到线程化子例程中
我有一个教科书上的例子,演示如何通过参数确定数据范围。我想知道为什么在下面的代码片段中,作者使用一个公共块来定义两个变量,istart和iend,**它们应该是每个线程的私有变量?具有公共属性的变量的“共享”属性是否与作者将**istart和iend指定为私有的意图相冲突?还是我们应该简单地删除公共块 作者说,“我们使用一个名为bounds的公共块,其中包含istart和iend,基本上包含主程序和子例程中使用的值。”我想知道每个线程的调用子例程是否会继承公共属性并干扰“private”istart和iend应承载的属性 背风 在另一个示例中,作者出于同样的目的编写了以下代码段。在这种情况下,我应该在主程序和子程序中保留公共块,对吗Parallel processing 将变量直接传递到线程化子例程中,parallel-processing,fortran,openmp,fortran-common-block,Parallel Processing,Fortran,Openmp,Fortran Common Block,我有一个教科书上的例子,演示如何通过参数确定数据范围。我想知道为什么在下面的代码片段中,作者使用一个公共块来定义两个变量,istart和iend,**它们应该是每个线程的私有变量?具有公共属性的变量的“共享”属性是否与作者将**istart和iend指定为私有的意图相冲突?还是我们应该简单地删除公共块 作者说,“我们使用一个名为bounds的公共块,其中包含istart和iend,基本上包含主程序和子例程中使用的值。”我想知道每个线程的调用子例程是否会继承公共属性并干扰“private”ista
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子句的参数不是公共块的名称):
如果这或多或少是一个完整的例子,我看不到公共块的任何位置。这里没有实际的共享,因为这些值对于
parallel
块中的每个线程都是私有的,并且它们作为伪参数传递
我真的会删除它
另一种情况则不同。这里使用公共块共享变量,并使用threadprivate
私有化变量。这是一个正确的用法,尽管更现代的风格是以同样的方式使用模块变量
对于模块,我会:
module parameters
integer :: istart,iend
!$omp threadprivate(istart,iend)
end module
module model
use parameters
implicit none
contains
subroutine work(iarray)
...
integer iarray(10000)
do i = istart, iend
iarray(i) = i * i
enddo
end subroutine work
end module model
program main
use parameters !not completely necessary here
use model
implicit none
...
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
请注意,threadprivate
指令仅用于声明其中使用的变量
备注,
common
不是变量的属性,它是包含变量的单独实体。因此,伪参数无法继承common
我有一个与此线程相关的派生问题。请再看我的帖子。谢谢。我已经扩展了答案。请看我在原始帖子底部对你建议的修改。看起来不错,只有threadprivate指令应该接近变量的定义。此外,如果更合适,变量可以在单独的模块中。那要视情况而定。谢谢。还有一个问题。你的意思是,除了主程序单元中的一个,我还需要放另一个$omp threadprivate(istart,iend)就在模块“模型”中“istart”和“iend”变量声明区域之后,而不是在本地过程——子程序“work”中?
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
module parameters
integer :: istart,iend
!$omp threadprivate(istart,iend)
end module
module model
use parameters
implicit none
contains
subroutine work(iarray)
...
integer iarray(10000)
do i = istart, iend
iarray(i) = i * i
enddo
end subroutine work
end module model
program main
use parameters !not completely necessary here
use model
implicit none
...
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