如何:转换使用缩减变量的 OpenMP 循环以使用并发运行时

本示例演示如何转换使用 reduction 子句的 OpenMP parallel for 循环,以便使用并发运行时。

您可以使用 OpenMP reduction 子句指定一个或多个与并行区域末端的缩减操作相关的线程专用变量。 OpenMP 预定义了一组缩减运算符。 每个缩减变量都必须是一个标量(例如,int、long 和 float)。 OpenMP 还定义了若干有关如何在并行区域中使用缩减变量的限制。

并行模式库 (PPL) 提供了 Concurrency::combinable 类,该类提供可重用的、线程本地存储,以允许您执行精细计算,然后再将这些计算合并为一个最终结果。 combinable 类是用于标量和复杂类型的模板。 若要使用 combinable 类,请在并行构造主体中执行子计算,然后调用 Concurrency::combinable::combineConcurrency::combinable::combine_each 方法以生成最终结果。 combinecombine_each 方法均会采用可指定每个元素对的组合方式的组合函数。 因此,combinable 类不仅限于一组固定的缩减运算符。

示例

此示例使用 OpenMP 和并发运行时计算前 35 个 Fibonacci 数的总和。

// concrt-omp-fibonacci-reduction.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <iostream>

using namespace Concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;

   // Compute the components in parallel.
   int n1, n2;
   parallel_invoke(
      [n,&n1] { n1 = fibonacci(n-1); },
      [n,&n2] { n2 = fibonacci(n-2); }
   );

   return n1 + n2;
}

// Uses OpenMP to compute the sum of Fibonacci numbers in parallel.
void omp_parallel_fibonacci_sum(int count)
{
   int sum = 0;
   #pragma omp parallel for reduction(+ : sum)
      for (int i = 0; i < count; ++i)
      {
         sum += fibonacci(i);
      }

   wcout << L"The sum of the first " << count << L" Fibonacci numbers is " 
         << sum << L'.' << endl;
}

// Uses the Concurrency Runtime to compute the sum of Fibonacci numbers in parallel.
void concrt_parallel_fibonacci_sum(int count) 
{
   combinable<int> sums;
   parallel_for(0, count, [&sums](int i)
      {
         sums.local() += fibonacci(i);
      });

   wcout << L"The sum of the first " << count << L" Fibonacci numbers is " 
         << sums.combine(plus<int>()) << L'.' << endl;
}

int wmain()
{
   const int count = 35;

   wcout << L"Using OpenMP..." << endl;
   omp_parallel_fibonacci_sum(count);

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_parallel_fibonacci_sum(count);
}

该示例产生下面的输出。

Using OpenMP...
The sum of the first 35 Fibonacci numbers is 14930351.
Using the Concurrency Runtime...
The sum of the first 35 Fibonacci numbers is 14930351.

有关 combinable 类的更多信息,请参见并行容器和对象

编译代码

复制该代码示例,并将其粘贴到 Visual Studio 项目中或名为 concrt-omp-fibonacci-reduction.cpp 的文件中,然后在 Visual Studio 2010 命令提示符窗口中运行以下命令。

cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp

请参见

概念

并行容器和对象

其他资源

从 OpenMP 迁移至并发运行时