OpenMP 特集に向けて

インテル® DPC++/C++ コンパイラーインテル® Fortran コンパイラー
今回は OpenMP に関する記事を特集しています。

OpenMP は最初の仕様書 1.0 が公開された後、2.0、2.5、3.0 とバージョンアップを重ね、現在は 2011年 7月に公開された 3.1 仕様が最新となっています。

仕様ごとに機能強化が行われているため、皆さんが利用するコンパイラーが OpenMP のどの仕様をサポートしているか知っておく必要があります。C/C++ および Fortran とも _OPENMP マクロを利用することで OpenMP 仕様のバージョンを知ることができ、このマクロは、プリプロセッサーとコンパイラー両方で条件付きコンパイルに利用できます。

_OPENMP マクロは、OpenMP 仕様がリリースされた年月を YYYYMM 形式の数値で返します。各 OpenMP 仕様が返す値は次のようになります。バージョン 2.5 以前は C/C++ と FORTRAN でマクロが返す値は異なりますが、2.5 からは統一されています。

仕様 言語 インテル® コンパイラーのバージョン
1.0 FORTRAN 199710 5.x
1.1 FORTRAN 199911 6.x
1.0 C/C++ 199811 6.x
2.0 FORTRAN 200011 7.x, 8.x
2.0 C/C++ 200203 7.x, 8.x
2.5 C/C++、FORTRAN 200505 9.x, 10.x
3.0 C/C++、FORTRAN 200805 11.x, 12.0
3.1 C/C++、FORTRAN 201107 12.1

例えば C 言語の場合、printf(“OpenMP version %d\n”, _OPENMP) でコンパイラーがサポートする仕様がリリースされた年月を表示できます。

OpenMP は幾つかの API をサポートしていますが、#pragma omp parallel や c$OMP PARALLEL 指示句は、コンパイラーに OpenMP 指示句の解釈を指示するオプション(-openmp)を指定しなければ無視されますが、API はリンク時にエラーとなります。

_OPENMP マクロを利用することで、次のような条件付きコンパイルが可能です。

#ifdef _OPENMP
     int thread_num = omp_get_thread_num();
#endif
また、仕様が異なる指示句の切り分けにも利用できます。例えば、C/C++ の OpenMP 2.0 では for 指示句を利用する for ループのループインデックスは、符号付き整数でなければいけませんが、3.0 ではそれ以外(符号なし整数やポインターなど)の幾つかのパターンが許されます。
#if (_OPENMP >= 200805)
     #pragma omp parallel for
     for( int *i = ptr; i < (i + MAX); i++)
          *i = 0;
#else if (_OPENMP < 200805)
     #pragma omp parallel for
     for( int i = 0; i < MAX; i++)
          a[i] = 0;
#endif
Visual C++ 2005 以降 2010 までは、OpenMP 2.0 の使用をサポートしていますので、Visual C++ を利用する場合 OpenMP 2.0 の仕様の範囲で並列構文を記述しなければいけません。GCC の場合は、4.2 以降 OpenMP を正式サポートしていますので、利用する GCC のバージョンでどの OpenMP 仕様が利用できるか、_OPENMP マクロで値を取得して確かめてください。

では、OpenMP 特集を活用ください。

OpenMP 特集記事
タイトルとURLをコピーしました