首页 > 解决方案 > 在不使用 OMP TASK 的情况下如何做到这一点?

问题描述

我有一个包含 4 个任务的数组,称为array. 声明如下: type(tcb),dimension(4)::arrray 

和:

type:: tcb !> new type task control block  
     procedure(my_interface),NOPASS,pointer:: f_ptr => null() !< the function pointer
     type(variables)::variables !< the variables 
     integer :: state     !< the task state
end type tcb

我只有 2 个线程来执行这 4 个任务。我想避免使用!$OMP TASK. 当我使用任务构造时,我得到了这样的东西:

type(tcb),dimension(4),intent(inout)::array !< the array of tasks
integer,intent(in)::ff !< the counter 
type(tcb)::self !< self
type(variables),intent(inout)::var !< the variables
!OpenMP variables
integer::num_thread !< the rank of the thread
integer::nthreads !< the number of threads
integer:: OMP_GET_THREAD_NUM !< function to get the rank of the thread
integer::OMP_GET_NUM_THREADS !< function to get the number of threads    

!=======================================================================================================================================================
!$OMP PARALLEL PRIVATE(num_thread,nthreads,ff) &
!$OMP SHARED(array)
num_thread=OMP_GET_THREAD_NUM() !< le rang du thread 
nthreads=OMP_GET_NUM_THREADS() !< le nombre de threads
       !$OMP MASTER
       do ff=1,3
             !$OMP TASK SHARED(array) IF ((num_thread .ne. 0) .and. (num_thread .ne. 1))
             call array(ff)%f_ptr(self,var)
             !$OMP END TASK
          end if
       end do
       !$OMP TASKWAIT 
       !$OMP END MASTER      

你有什么主意吗 ?我希望当线程完成运行任务时,它直接移动到下一个可用任务。它不应该等待另一个线程完成。不使用 OMP Tasking 怎么办?我想单独安排任务,而不是借助 OpenMP。是否可以 ?

标签: multithreadingfortrantaskopenmpthreadpool

解决方案


使用 OpenMP 指令,您已经创建了一个串行程序。在这里,我试图解释原因。您的代码中的任务创建位于 MASTER 区域内,其中num_thread始终为零。从规范

线程编号:OpenMP 实现分配给 OpenMP 线程的编号。对于同一组内的线程,零标识主线程,连续数字标识该组的其他线程。

因此((num_thread .ne. 0) .and. (num_thread .ne. 1))表达式总是错误的。再次来自规范

当一个if子句出现在一个任务构造上,并且该if 子句表达式的计算结果为假时,就会生成一个未延迟的任务,并且遇到的线程必须挂起当前任务区域,在生成的任务完成之前无法恢复执行

所以,这意味着你有一个串行程序。主线程执行暂停,直到任务完成。虽然标准没有要求(或指定),但实际上这意味着您的程序将仅在主线程上运行,其他线程只是等待。因此,您必须删除该if子句,您的程序将是并发的。

如果您希望仅在 2 个线程上运行这些任务,则必须使用num_threads(2)并行区域子句来明确指定它。

编辑:要回答您的问题,使用任务是一个不错的选择,但是如果在编译时知道任务的数量,您也可以使用部分

!$omp sections
  !$omp section
    ! first job is here
  !$omp section 
    ! second job is here
  ...
!$omp end sections

ps:你提到了4个任务,但是你的代码只生成了其中的3个。ps2:end if不需要。


推荐阅读