在线程子程序调用的函数中使用全局变量

时间:2014-03-01 05:45:34

标签: multithreading parallel-processing openmp fortran90

我正在学习如何将我的FORTRAN源代码移植到Openmp,并遇到了一个关于如何处理包含调用子例程所在的并行区域之前定义的全局变量的线程子例程的基本问题。

以下是我为该问题编写的示例代码。我将一系列值从1乘以1000000,由全局变量“p1”命名为“a”。乘法由并行执行托管子程序来执行,该子程序调用函数“afun”以进行逐元素乘法a(i)* p1并将相应结果保存到对应的b(i)。 “p1”的值在并行区域之外分配,因此是子程序“asub”的全局变量,并且其被称为函数“afun”。

我可以问一下,成功运行该程序需要哪些额外的Openmp配置?

program common_test
    use omp_lib
    implicit none
    integer :: a(100000),b(100000)
    integer :: p1,i
    common /p_com/ p1
    !$omp threadprivate(/p_com/)
    do i=1,100000
        a(i)=i
    enddo
    p1=2
    !$omp parallel do shared(a,b) private(i) copyin(p1)
    do i=1,100000
        call asub(afun,i,b(i))
    enddo
    !$omp end parallel do
contains
    subroutine asub(func,x,y)
        implicit none
        interface
           function func(x,p)
           implicit none
           integer :: x,p,func
           end function func    
        end interface
        integer, intent(in) :: x
        integer, intent(out) :: y
        integer :: p1
        common /p_com/ p1
        y=func(x,p1)    
    end subroutine asub

    function afun(x,p)
        implicit none
        integer, intent(in) :: x
        integer :: p,afun
        afun=x*p
    end function afun
end program common_test

1 个答案:

答案 0 :(得分:0)

我终于在没有收到英特尔编译器投诉的情况下运行了示例代码。我所做的更正是在主程序中第二个Openmp指令行的末尾用copyin(/ p_com /)替换copyin(p1)。也就是说,

program common_test
    use omp_lib
    implicit none
    integer :: a(100000),b(100000)
    integer :: p1,i
    common /p_com/ p1

    !$omp threadprivate(/p_com/)
    do i=1,100000
        a(i)=i
    enddo

    p1=2
    !$omp parallel do shared(a,b) private(i) copyin(/p_com/)
    do i=1,100000
        call asub(afun,i,b(i))
    enddo
    !$omp end parallel do
contains
    subroutine asub(func,x,y)
        implicit none
        interface
        function func(x,p)
        implicit none
        integer :: x,p,func
        end function func    
        end interface
        integer, intent(in) :: x
        integer, intent(out) :: y
        integer :: p1
        common /p_com/ p1
        y=func(x,p1)    
    end subroutine asub

    function afun(x,p)
        implicit none
        integer, intent(in) :: x
        integer :: p,afun
        afun=x*p
    end function afun
end program common_test