並列リダクション
全体に渡って、総和・最大値・最小値・論理積などを求めることをリダクションと呼びます。並列的なリダクション処理を実装するのは少々難しいですが、幸いOpenMPには簡単に並列リダクションを実装するためにreduction
指示句が用意されています。
サンプルプロジェクトReductionSample
のコードを掲載しますので、先ずはこのコードを見てください。
#include <stdio.h> #include <omp.h> int main() { int i, count, sum; count = 0; sum = 0; #pragma omp parallel num_threads( 10 ) reduction( +: count, sum ) { #pragma for for ( i = 0; i < 10; i++ ) { count++; sum += i; } printf( "スレッド:%d\t実行回数%d回 合計値%d\n", omp_get_thread_num(), count, sum ); } /* 最終値を表示 */ printf( "【最終値】\t実行回数%d回 合計値%d\n\n", count, sum ); return 0; }
このサンプルを実行すると、総合計を並列的に算出します。前回掲載した総合計を求めるfork-joinモデルのサンプルと見比べてください。OpenMPを使用すると、並列リダクション処理を、簡単に実装できることが分かります。
OpenMPを用いて並列リダクション処理を行いたい場合、reduction
指示句を指定するだけです。reduction
指示句は、括弧内に「オペレーション(+、*などの符号):使用する変数(複数指定可能)」を記述するだけです。もし、複数の演算を行いたい場合は、reduction
指示句を演算の数だけ指定します。
まとめ
今回はOpenMPの変数に関する指示句を紹介しました。前回の記事と併せて読むと、並列処理での変数の扱い方について多くのことが分かったと思います。並列処理において、変数の扱い方は非常に重要です。変数の使い方を理解しないと、正しく並列プログラミングをすることはできず、バグに悩まされる羽目になります。
変数の扱い方をマスターすれば、並列処理特有のバグを大幅に減らすことができます。本記事が、並列処理特有のバグを減らす一助になれば幸いです。
次回は、より高度なOpenMPの概念を解説します。お楽しみに。
参考資料
- MSDN
- OpenMP公式ホームページ
- 『OpenMP入門』 北山洋幸 著、秀和システム、2009年8月