次の方法で共有


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

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

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

並列パターン ライブラリ (PPL) には、Concurrency::combinable クラスが用意されています。このクラスが提供する再利用可能なスレッド ローカル ストレージを使用すると、詳細な計算を実行した後、その計算を最終結果にマージできます。 combinable クラスは、スカラー型と複合型の両方に作用するテンプレートです。 combinable クラスを使用するには、parallel コンストラクトの本体でサブ計算を実行してから、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-fibonacci-reduction.cpp という名前のファイルに貼り付け、Visual Studio 2010 のコマンド プロンプト ウィンドウで次のコマンドを実行します。

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

参照

概念

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

その他の技術情報

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