Oracle® Developer Studio 12.5:OpenMP API 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

4.1 OpenMP 任务处理模型

任务处理功能有助于应用程序的并行化,其中工作单元是动态生成的,就像在递归结构或 while 循环中一样。

4.1.1 OpenMP 任务执行

在 OpenMP 中,显式任务使用 task 构造指定,该构造可放置在程序中的任一位置。只要线程遇到 task 构造,就会生成一个新任务。

当线程遇到 task 构造时,可以选择立即执行任务或将任务延迟到稍后某个时间再执行。如果延迟执行任务,则任务会被放置在与当前并行区域关联的概念任务池中。当前组中的线程会将任务从该池中取出,并执行这些任务,直到该池为空。执行任务的线程可能不是最初遇到该任务并将该任务放在池中的线程。

与任务关联的代码仅执行一次。如果代码从始至终都必须由相同的线程执行,则任务为绑定 (tied) 任务。如果代码可由多个线程执行,即由不同的线程执行任务代码的不同部分,则任务为非绑定 (untied) 任务。缺省情况下,任务为绑定 (tied) 任务,可以通过在 task 指令中使用 untied 子句将任务指定为非绑定 (untied) 任务。

允许线程在任务调度点暂停执行任务区域,以便执行另一任务。如果暂停的任务为绑定 (tied) 任务,则同一线程稍后会恢复执行暂停的任务。如果暂停的任务为非绑定 (untied) 任务,则当前组中的任何线程都可能会恢复执行该任务。

任务调度点隐含在多个位置中,包括以下位置:

  • 紧随在显式任务生成之后的点

  • task 区域完成点之后的位置

  • taskyield 区域中

  • taskwait 区域中

  • taskgroup 区域末尾

  • 在隐式和显式 barrier 区域中

除了使用 task 构造指定的显式任务外,OpenMP 规范还介绍了隐式任务的概念。隐式任务是由隐式并行区域生成的任务,或是在执行期间遇到 parallel 构造时生成的任务。在后一种情况中,每个隐式任务的代码都是 parallel 构造内的代码。每个隐式任务分配给组中不同的线程,且为绑定 (tied) 任务。

对于在遇到 parallel 构造时生成的所有隐式任务,都要保证在主线程退出并行区域末尾的隐式屏障时完成。另一方面,对于在并行区域中生成的所有显式任务,都要保证在从并行区域中的下一个隐式或显式屏障退出时完成。

4.1.2 OpenMP 任务类型

OpenMP 规范定义了各种类型的任务,程序员可以使用这些任务来减少任务处理开销。

不延迟 (undeferred) 任务是指相对于生成任务,不会延迟执行的任务;也就是说,在不延迟 (undeferred) 任务执行完成前,生成任务区域会暂停。不延迟 (undeferred) 任务可能不会被遇到该任务的线程立即执行。它可能会被放置在池中,然后由遇到该任务的线程或某个其他线程稍后执行。任务执行完成后,生成任务才会恢复执行。例如,if 子句表达式求值结果为 false 的任务即是一个不延迟 (undeferred) 任务。在这种情况下,将生成不延迟 (undeferred) 任务,且遇到该任务的线程必须暂停当前的任务区域。在包含 if 子句的任务完成前,不会恢复当前任务区域的执行。

与不延迟 (undeferred) 任务不同,包括 (included) 任务将由遇到该任务的线程立即执行,而不会放在池中稍后执行。此类任务的执行按顺序包含在生成任务区域中。与不延迟 (undeferred) 任务一样,在包括 (included) 任务的执行完成前将暂停生成任务,执行完成后才会恢复生成任务。举例来说,包括 (included) 任务是最终 (final) 任务的子孙。

合并 (merged) 任务是指其数据环境与其生成任务区域的数据环境一样的任务。如果 mergeable 子句存在于 task 指令中,且生成的任务为不延迟 (undeferred) 任务或包括 (included) 任务,则实现可能会选择生成合并 (merged) 任务。如果生成合并 (merged) 任务,则相应行为就好像根本没有 task 指令一样。

最终 (final) 任务是指会强制其所有子孙任务都成为最终 (final) 和包括 (included) 任务的任务。当 final 子句存在于 task 指令中,且 final 子句表达式求值结果为 true 时,生成的任务将为最终 (final) 任务。