方法: 減少変数を使用する OpenMP ループを変換し、同時実行ランタイムを使用する

この例では、reduction 句を使用する OpenMP parallelfor ループを同時実行ランタイムの使用に切り替える方法を示します。

OpenMP reduction 句を使用すると、並列領域の最後にあるリダクション演算の対象となる 1 つ以上のスレッド プライベート変数を指定できます。OpenMP には、リダクション演算子のセットがあらかじめ定義されています。各リダクション変数はスカラー (int、long、float など) にする必要があります。OpenMP には、並列領域でのリダクション変数の使用方法に関する制限事項もいくつか定義されています。

並列パターン ライブラリ (PPL) を提供する、 concurrency::combinable 、きめ細かな計算を実行し、これらの計算は、最終的な結果にマージすることができます再利用可能なスレッド ローカル記憶域を提供するクラス。combinable クラスは、スカラー型と複合型の両方に作用するテンプレートです。使用するのには、 combinableクラス、parallel コンストラクトの本文に sub-computations を実行し、呼び出しを concurrency::combinable::combine または concurrency::combinable::combine_each 、最終的な結果を生成するメソッド。combinecombine_each の各メソッドは、combine 関数を使用して各要素ペアを結合する方法を指定します。したがって、combinable クラスは、リダクション演算子の固定セットだけに制限されません。

使用例

この例では、OpenMP と同時実行ランタイムの両方を使用して、最初の 35 個のフィボナッチ数の合計を計算します。

// 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

参照

概念

OpenMP から同時実行ランタイムへの移行

並列コンテナーと並列オブジェクト