最近,我不得不将一个用fortran编写的串行程序更改为并行版本,以便更快地获得结果。但是我遇到了一些问题。并行Fortran程序将在特定时间睡眠
我正在使用ubuntu os和gfortran编译器,至于并行API,我使用的是OpeMP。在以前的(串行)版本中,我使用了许多模块来共享数据,但是在openmp版本中,我使用变量threadprivate属性,并且其中一些变量具有可分配属性。在之前的版本中,我在do循环之前为变量分配空间,但在openmp版本中,如果我这样做,程序将报告错误为无效的内存引用,尽管我给它指定了threadprivate属性。所以我在循环中分配变量并在循环中释放它。我在并行区域做了do循环。它没有错误,程序可以运行。但还有另一个问题。由于它运行大约800分钟的CPU时间,并且我使用ps -ux命令查看该并行程序的状态,其状态从R1改变为S1。我搜索S的意思,它代表
中断睡眠(等待一个事件来完成)
那么,为什么这个问题出现?是否因为我经常分配和释放空间?以下是示例代码:
module variables
real, dimension(:), allocatable, save :: a
real, dimension(:,:), allocatable, save :: b
!$omp threadprivate(a,b)
integer, parameter :: n=100
contains
subroutine alloc_var
integer :: status
allocate(a(100),stat=status)
allocate(b(100:100),stat=status)
end subroutine
subroutine free_var
integer :: status
deallocate(a,stat=status)
deallocate(b,stat=status)
end subroutine
end module
对于其他子程序,有一些使用变量a和b。
subroutine cal_sth
use variables, only a
...
end subroutine
串行版本主程序
program main
implicit none
external :: cal_sth
use variables, only alloc_var,free_var
integer :: i, j
call alloc_var
do j=1, count1
...
other expresion ...
do i=1, count2
call cal_sth
end do
end do
call free_var
end program
为并行区域,
program main
implicit none
external :: cal_sth
use variables, only alloc_var, free_var
integer :: i,j
!$omp parallel do private(i,j)
do j=1, count1
...
other expression ...
do i=1, count2
call alloc_var
call cal_sth
if (logical expression) then
call free_var
cycle
end if
call free_var
end do
end do
end program
你为什么不只是初始化了''和'B'一劳永逸内专用'平行区域?像:'!$ omp parallel''调用alloc_var''!$ omp end parallel' – Gilles