Function 被调用函数在OpenMP并行区域中有自己的继承变量
下面示例的目的是在名为“sub1”的子例程上并行化do循环,该子例程调用执行简单加法操作的函数 困扰我的问题是,在我的数学模型中,被调用的函数有两个输入参数(a,e),但在我的代码中,由于某种原因,我被限制将一个参数函数传递给子程序“sub1”。我想出的解决方案是设置第二个变量“e”由被调用函数从其驻留的模块继承。我觉得结果不错 我想知道使用heritage将多个参数(在调用函数所在的模块中定义相同)传递给并行区域中的调用函数是否会导致任何争用问题 谢谢 背风 ----本例中有两个文件:main.f90和model.f90 MAIN.f90Function 被调用函数在OpenMP并行区域中有自己的继承变量,function,parallel-processing,fortran,openmp,fortran90,Function,Parallel Processing,Fortran,Openmp,Fortran90,下面示例的目的是在名为“sub1”的子例程上并行化do循环,该子例程调用执行简单加法操作的函数 困扰我的问题是,在我的数学模型中,被调用的函数有两个输入参数(a,e),但在我的代码中,由于某种原因,我被限制将一个参数函数传递给子程序“sub1”。我想出的解决方案是设置第二个变量“e”由被调用函数从其驻留的模块继承。我觉得结果不错 我想知道使用heritage将多个参数(在调用函数所在的模块中定义相同)传递给并行区域中的调用函数是否会导致任何争用问题 谢谢 背风 ----本例中有两个文件:main
program main
! The definition of sub1 is:
! taking function_1,input_2,input_3 as inputs and
! returning output_4 as output
use omp_lib
use model
implicit none
integer :: j
real :: m(1000),k(1000)
m=[(real(j),j=1,1000)]
!$omp parallel do private(j) shared(m,k)
do j=1,1000
call sub1(fun1,m(j),2.,k(j))
enddo
!$omp end parallel do
end program main
型号1.F90
module model
implicit none
real :: e
contains
subroutine sub1(func,a,c,d)
implicit none
real, intent(in) :: a,c
real, intent(out) :: d
interface
real function func(a)
implicit none
real :: a
end function func
end interface
e=c
d=func(a)
end subroutine sub1
real function fun1(a)
implicit none
real :: a
fun1=a**e
end function fun1
end module model
是的,更多线程将尝试写入此行中的变量
e
e=c
这是一个比赛条件。你能做到的。这样,每个线程都将拥有其私有副本,该副本将在调用期间保持
在Fortran 2008中,您也可以按照下面的程序执行某些操作,但原理是一样的
module model
implicit none
real :: e
contains
subroutine sub2(func,a,d)
implicit none
real, intent(in) :: a
real, intent(out) :: d
interface
real function func(a)
implicit none
real :: a
end function func
end interface
d=func(a)
end subroutine
end module model
program main
! The definition of sub1 is:
! taking function_1,input_2,input_3 as inputs and
! returning output_4 as output
use omp_lib
use model
implicit none
integer :: j
real :: c
real :: m(1000),k(1000)
m=[(real(j),j=1,1000)]
!$omp parallel do private(j,c) shared(m,k)
do j=1,1000
c = i
call sub2(fun1,m(j),k(j))
enddo
!$omp end parallel do
contains
real function fun1(a)
implicit none
real :: a
fun1=a**c
end function fun1
end program main
我想问一下,既然c是子程序“sub1”的局部变量,为什么c是导致赛车问题的罪魁祸首?此外,变量“e”是否被复制,以便在并行区域的开头,每个线程都有自己的“e”变量?感谢您的帮助。
e
是一个模块变量。所有模块变量均隐式保存。因此,除非您通过某个openmp
指令更改了行为,否则所有过程实例都会共享它们<代码>c在这里是不相关的。我明白了。但是,我使用的编译器是PGI Fortran,它不支持Fortran 2008约定。:D顺便说一句,如果函数fun1在一个单独的文件中定义为一个外部函数,该怎么办?Fortan 2008仅用于我的示例,您可以忽略它。如果fun1是外部的,则取决于您如何实现有问题的变量,该功能仍可使用该模块。