一旦“生成例程”退出,OpenMP 任务就会崩溃

问题描述 投票:0回答:1

我有以下程序结构:

type(mytype) :: x(10)

!$OMP PARALLEL DEFAULT(SHARED)
!$OMP MASTER
do i = 1, 10
   call sub1(x(i)) ! some stuff that cannot be parallelized
   call sub2(x(i)) ! some stuff that can be parallelized once sub1 has completed
!$OMP END MASTER
!$OMP END PARALLEL

[.....]

subroutine sub2(x)
   type(mytype), intent(inout) :: x
   integer :: j, k
   integer, allocatable :: v(:)
   allocate( v(10000) ) 
   v(:) = ... ! filling up v
   do j = 1, 1000
      !$OMP TASK DEFAULT(NONE) SHARED(x) PRIVATE(k) FIRSTPRIVATE(j,v)
         !...working on x
      !$OMP END TASK
   end do
end subroutine

但它的表现并不如预期:

    仅在 1000 个任务(每个任务需要几秒钟)中的许多任务完成后,
  • 主线程才会退出
    sub2()
    。是因为初始化任务需要花费大量时间(特别是为每个任务复制
    firstprivate
    数组)吗?
  • 更烦人的是,一旦主线程退出,程序就会在其中一个任务中崩溃,并出现内存错误(调试器中的“空指针取消引用或未对齐的内存访问”消息)。我不明白为什么会发生这种情况,因为:
  • 任务中使用的所有虚拟参数都声明为 
    sub2()
      ,因此只要程序位于并行区域中,就应该保持可访问性
    • 任务中使用的所有局部变量都声明为 
      SHARED
    • PRIVATE
      ,因此应具有与任务本身相同的生命周期
      
      
    我在这里缺少什么?
编译器是Intel ifort 2018

根据我所做的评论和一些附加测试,事实证明,在所有任务完成之前,不得退出已生成某些任务的例程。一个解决方案是在例程末尾放置一个
fortran openmp intel-fortran
1个回答
0
投票
指令,但这不符合我最初的目标,我希望主线程在执行任务时执行

taskwait

 的所有迭代。我最终得到了一个解决方案,其中将对 
sub1()
 的调用包含在任务中:这样,主线程可以继续执行,而无需等待 
sub2()
 退出:
sub2()


© www.soinside.com 2019 - 2024. All rights reserved.