在我看来,使用OpenMP时,可以用来跨子程序保存全局变量的fortran模块不起作用.这是一个例子:
main.f90时
program main
use mod
implicit none
!$OMP PARALLEL private(a)
!$OMP DO
do i=1,10
a=i-1
print*,"a =",a
call echo
print*,"b =",b
enddo
!$OMP END DO
!$OMP END PARALLEL
end program main
Run Code Online (Sandbox Code Playgroud)
echo.f90
subroutine echo
use mod
implicit none
b=a+1
!print *,a,"+1=",b
end subroutine echo
Run Code Online (Sandbox Code Playgroud)
mod.f90
module mod
integer:: i,a,b
end module mod
Run Code Online (Sandbox Code Playgroud)
现在如果你在没有OpenMP的情况下编译并运行它,你会得到:
a = 0
b = 1
a = 1
b = 2
a = 2
Run Code Online (Sandbox Code Playgroud)
.....等.这是你所期望的
但是,如果您使用openMP进行编译,则会得到:
a = 7
b = 1
a = 6
b = 1
a = 8
Run Code Online (Sandbox Code Playgroud)
.....等.这不是我想要的.我知道echo子例程从模块获得'a',而不是线程拥有的私有'a'.有什么方法可以做到这一点,除了作为一个论点传递?我的模块中有很多变量,这将是乏味的.
Ian*_*anH 10
在过程中echo,a并且b是在区域中引用但在构造中没有引用的变量 - 执行方面它们出现在匹配!$OMP PARALLEL和!$OMP END PARALLEL指令之间,但是源代码却没有.由于它们是模块变量,并且在没有相反的指令的情况下,OpemMP 4.0标准的2.14.1.2中的数据共享属性规则指定了过程内的那些变量是共享的.
因此,您的示例代码具有数据争用,多个线程b在echo没有同步的情况下写入子例程内部.
您可以在模块中使用THREADPRIVATE指令来更改这些模块变量的数据共享属性.您需要同时删除私有规范a.
从长远来看,一个更好的方法可能是通过将信息作为参数传递(可能在派生类型中捆绑在一起),使程序中的信息流显式地呈现给代码的读者(并且更灵活地由代码编写器配置)而不是通过使用全局(模块)变量隐藏这些流.
| 归档时间: |
|
| 查看次数: |
1666 次 |
| 最近记录: |