如何用等待功能替换 OMP BARRIER?
How can I replace an OMP BARRIER by a wait function?
我想停用下面代码中的 !$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_start
和 omp_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_start
和 omp_end
由线程 1
设置并由其他线程读取。正如您目前所拥有的那样,发生这种情况的顺序是未定义的,因此它们可以(并且很可能会)在设置之前被读取。
然而还有一个更根本的问题。看起来您只是想让其他线程等待线程 1
完成,但无法提前知道这需要多长时间。因此,没有办法实现这样的等待功能。这就是首先使用障碍的全部原因。
我想停用下面代码中的 !$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_start
和 omp_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_start
和 omp_end
由线程 1
设置并由其他线程读取。正如您目前所拥有的那样,发生这种情况的顺序是未定义的,因此它们可以(并且很可能会)在设置之前被读取。
然而还有一个更根本的问题。看起来您只是想让其他线程等待线程 1
完成,但无法提前知道这需要多长时间。因此,没有办法实现这样的等待功能。这就是首先使用障碍的全部原因。