Function 被调用函数在OpenMP并行区域中有自己的继承变量

Function 被调用函数在OpenMP并行区域中有自己的继承变量,function,parallel-processing,fortran,openmp,fortran90,Function,Parallel Processing,Fortran,Openmp,Fortran90,下面示例的目的是在名为“sub1”的子例程上并行化do循环,该子例程调用执行简单加法操作的函数 困扰我的问题是,在我的数学模型中,被调用的函数有两个输入参数(a,e),但在我的代码中,由于某种原因,我被限制将一个参数函数传递给子程序“sub1”。我想出的解决方案是设置第二个变量“e”由被调用函数从其驻留的模块继承。我觉得结果不错 我想知道使用heritage将多个参数(在调用函数所在的模块中定义相同)传递给并行区域中的调用函数是否会导致任何争用问题 谢谢 背风 ----本例中有两个文件:main

下面示例的目的是在名为“sub1”的子例程上并行化do循环,该子例程调用执行简单加法操作的函数

困扰我的问题是,在我的数学模型中,被调用的函数有两个输入参数(a,e),但在我的代码中,由于某种原因,我被限制将一个参数函数传递给子程序“sub1”。我想出的解决方案是设置第二个变量“e”由被调用函数从其驻留的模块继承。我觉得结果不错

我想知道使用heritage将多个参数(在调用函数所在的模块中定义相同)传递给并行区域中的调用函数是否会导致任何争用问题

谢谢

背风

----本例中有两个文件:main.f90和model.f90

MAIN.f90

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是外部的,则取决于您如何实现有问题的变量,该功能仍可使用该模块。