在不使用 OMP TASK 的情况下如何做到这一点?

Posted

技术标签:

【中文标题】在不使用 OMP TASK 的情况下如何做到这一点?【英文标题】:How can I do this without using OMP TASK? 【发布时间】:2021-09-24 07:13:01 【问题描述】:

我有一个名为 array 的 4 个任务数组。声明如下: 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。有可能吗?

【问题讨论】:

您想要的正是 OpenMP 任务的工作方式。一旦一个线程完成了一项任务,它将寻找下一个准备好执行的可用任务。我不明白你为什么不想使用 OpenMP 任务。您能否更具体地说明“等待另一个线程完成”的含义?在您的代码中发生这种情况的唯一方法是所有线程都必须等到所有线程在并行区域结束时完成。但这是你无法避免的。 【参考方案1】:

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

线程编号:OpenMP 实现分配给线程的编号 OpenMP 线程。对于同一团队中的线程,零表示 主线程和连续的数字标识其他线程 这个团队的成员。

因此((num_thread .ne. 0) .and. (num_thread .ne. 1)) 表达式始终为假。再次来自specification:

当一个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

【讨论】:

@hakim 如果这解决了您的问题,请接受答案,以便其他人可以看到您的问题已解决。另一方面,如果您需要更多信息,请告诉我们。

以上是关于在不使用 OMP TASK 的情况下如何做到这一点?的主要内容,如果未能解决你的问题,请参考以下文章

我想每次添加不同的图像,我重复使用这张卡片。如何在不复制粘贴整个代码的情况下做到这一点

如何在不破坏 CakePHP 中的 MVC 框架的情况下做到这一点?

哈希表调整大小:我们如何在不知道密钥的情况下做到这一点?

在不处理的情况下在线获取信用卡信息——如何最好地做到这一点?

Ajax“有新内容吗?如果有,更新页面”——如何在不破坏服务器的情况下做到这一点?

在不淹没客户端的情况下推送更新事件。干净的方式来做到这一点?