【问题标题】:How can I replace an OMP BARRIER by a wait function?如何用等待功能替换 OMP BARRIER?
【发布时间】:2021-10-31 19:04:20
【问题描述】:

我想停用以下代码中的!$OMP BARRIER,所以我想用wait 函数替换它。

!$OMP BARRIER:

 if (num_thread==1) then
          do i_task=first_task,last_task
             tasklist_GRAD(i_task)%state=STATE_READY
             call queue_enqueue_data(master_queue,tasklist_GRAD(i_task))   !< add the list elements to the queue (full queue)
          end do
 end if

   
 !$OMP BARRIER     ! barrier to retire 

 call master_worker_execution(self,var,master_queue,worker_queue,first_task,last_task,nthreads,num_thread,lck)

没有!$OMP BARRIER

if (num_thread==1) then
          omp_start=omp_get_wtime() !start 
          do i_task=first_task,last_task
             tasklist_GRAD(i_task)%state=STATE_READY
             call queue_enqueue_data(master_queue,tasklist_GRAD(i_task))   !< add the list elements to the queue (full queue)
          end do
          omp_end=omp_get_wtime() !end 
end if


   


if (num_thread .ne. 1) then 
         call wait(int(omp_end-omp_start)*1000)
end if
           
call master_worker_execution(self,var,master_queue,worker_queue,first_task,last_task,nthreads,num_thread,lck)

wait子程序的定义:

 subroutine wait(omp_start,omp_end)
    real(kind=REAL64),intent(in)::omp_start,omp_end
    real(kind=REAL64)::time 
    time=omp_end-omp_start
    call sleep(int(time))
  end subroutine wait

屏障应该让线程(不是线程号 1)等待线程号 1 完成对 master_queue 的排队。这就是为什么我想用 wait 函数替换它。

执行时,由于线程安全(我猜),我得到一个段错误。我对使用INT 函数有疑问,因为我将omp_startomp_end 声明为real(kind=REAL64)

编辑: 我根据得到的答案修改了wait 子程序并做了以下操作:

subroutine wait(master_queue)
    type(QUEUE_STRUCT),pointer::master_queue !< the master queue of tasks
    do while (.not. queue_full(master_queue))
       call sleep(1)
    end do
  end subroutine wait

很遗憾,我没有像 OMP_BARRIER 那样得到结果。

logical function queue_full( queue )
    type(QUEUE_STRUCT), intent(in)  :: queue

    queue_full = (queue%size == queue%capacity)

  end function queue_full

【问题讨论】:

  • 了解您为什么不想使用OMP_BARRIER 会有所帮助。
  • @veryreverie 我正试图摆脱OMP_BARRIER,因为我必须从单节点切换到多节点。 OMP_BARRIER 在您有多个节点时不起作用,所以我正在尝试准备代码,以便它也可以在多节点中工作。我通过从头开始实现 OMP_TASK 摆脱了它,但我仍然有 OMP_BARRIERs 需要替换。还有其他方法吗?
  • 啊,在这种情况下,您需要将 OMP_BARRIER 替换为您正在使用的任何多节点框架(例如 MPI)中的等效项。
  • 看来您遇到了新问题。反正不知道queue_full是什么,没人能诊断出来。
  • 它告诉变量可以被程序的其他部分以异步方式修改 - 例如由其他线程。对于queue_full = (queue%size == queue%capacity) 行,您可能还需要一些原子或关键指令。

标签: multithreading fortran openmp gfortran barrier


【解决方案1】:

出现段错误的原因是 omp_startomp_end 由线程 1 设置并由其他线程读取。正如您目前所拥有的那样,发生这种情况的顺序是未定义的,因此可以(并且可能会)在设置之前读取它们。

然而,还有一个更根本的问题。看起来您只是希望其他线程等待线程1 完成,但无法提前知道这需要多长时间。因此,没有办法实现这样的等待功能。这就是首先使用屏障的全部原因。

【讨论】:

  • 是的,没错,我刚刚意识到其他线程没有 omp_start 和 omp_end 的值,即使它们被声明为共享变量。他们必须等待获得这些价值观,而这根本不是我的意图。谢谢!
猜你喜欢
  • 2018-07-10
  • 2017-12-08
  • 1970-01-01
  • 2019-04-22
  • 2020-08-14
  • 2021-10-29
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多