如何:转换使用缩减变量的 OpenMP 循环以使用并发运行时
本示例演示如何转换使用 减少 子句的 OpenMP parallel for 循环,以便使用并发运行时。
您可以使用 OpenMP reduction 子句指定一个或多个与并行区域末端的缩减操作相关的线程专用变量。 OpenMP 预定义了一组缩减运算符。 每个缩减变量都必须是一个标量(例如,int、long 和 float)。 OpenMP 还定义了若干有关如何在并行区域中使用缩减变量的限制。
提供了并行模式库 (PPL) concurrency::combinable 类,它提供了可重复使用、 线程本地存储,您可以执行精确计算,然后将这些计算合并到最终的结果。 combinable 类是用于标量和复杂类型的模板。 若要使用combinable类,一种平行构造的正文中执行 sub-computations,然后调用 concurrency::combinable::combine 或 concurrency::combinable::combine_each 方法以生成最终的结果。 combine 和 combine_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 斐波纳契 reduction.cpp ,然后在 Visual Studio 命令提示符窗口中运行以下命令。
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp