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

退出打印视图

更新时间: 2016 年 7 月
 
 

4.3 任务处理示例

本节中的 C/C++ 示例说明如何用 OpenMP tasktaskwait 指令递归计算斐波纳契数。

在本例中,并行区域由四个线程执行。single 区域确保只由其中一个线程执行调用 fib(n)print 语句。

fib(n) 的调用会生成两个任务(由 task 指令指示)。其中一个任务调用 fib(n-1),另一个任务调用 fib(n-2),将这些调用的返回值加在一起即可产生由 fib(n) 返回的值。对 fib(n-1)fib(n-2) 的每个调用会进而生成两个任务,这两个任务递归生成,直到传递给 fib() 的参数小于 2。

请注意每个 task 指令中的 final 子句。如果 final 子句表达式 (n <= THRESHOLD) 求值结果为 true,则生成的任务将为最终 (final) 任务。执行最终 (final) 任务期间遇到的所有 task 构造将生成包括 (included) 和最终 (final) 任务。当使用参数 n = 9, 8, ..., 2 调用 fib() 时,将生成包括 (included) 任务。这些任务将由遇到这些任务的线程立即执行,从而减少在池中放置任务的开销。

taskwait 指令可确保在调用 fib() 的同一过程中生成的两个任务(即计算 ij 的任务)在对 fib() 的调用返回之前已完成。

请注意,虽然只有一个线程执行 single 指令(因而只有第一个线程调用 fib()),但是所有四个线程都将参与执行生成的任务和放在池中的任务。

示例 3  使用任务计算斐波纳契数
#include <stdio.h>
#include <omp.h>

#define THRESHOLD 9

int fib(int n)
{
  int i, j;
 
  if (n<2)
    return n;
 
  #pragma omp task shared(i) firstprivate(n) final(n <= THRESHOLD)
  i=fib(n-1);
 
  #pragma omp task shared(j) firstprivate(n) final(n <= THRESHOLD)
  j=fib(n-2);
 
  #pragma omp taskwait
  return i+j;
}


int main()
{
  int n = 30;
  omp_set_dynamic(0);
  omp_set_num_threads(4);
 
  #pragma omp parallel shared(n)
  {
     #pragma omp single
     printf ("fib(%d) = %d\n", n, fib(n));
  }
}

% CC -xopenmp -xO3 task_example.cc

% a.out
fib(30) = 832040