サーチ…


パラメーター

パラメータ
private コンマで区切られたプライベート変数のリスト
firstprivate privateと同様ですが、ループに入る前に変数の値に初期化されます
lastprivate privateと同様ですが、変数は終了時にループの最後の反復に対応する値を取得します
reduction リダクション演算子:対応するリダクション変数のコンマ区切りリスト
schedule staticdynamicguidedautoまたはruntimeの3つの昏睡状態の後の任意のチャンクサイズ
collapse 折りたたまれて並列化される完全にネストされたループの数
ordered ループのいくつかの部分を順番に保つ必要があることを伝えます(これらの部分は、ループ本体の中でいくつかのordered節で特定されます)
nowait ループ構成の最後にデフォルトで存在する暗黙のバリアを削除する

備考

schedule句の意味は次のとおりです。

  • static[,chunk] :ラウンドロビン方式でchunkサイズのバッチでループ反復を静的に(つまり、ループに入る前に配布が行われることを意味して)分散します。 chunkが指定されていない場合、 chunkは可能な限り均等であり、各スレッドは最大で1つのスレッドを取得します。
  • dynamic[,chunk] :バッチが残らなくなるまで先入れ先出しポリシーでスレッドのchunkサイズをバッチ単位でループ間で繰り返します。指定しない場合、 chunkは1に設定されます
  • guided[,chunk]dynamicと同じように、バッチサイズが小さくなり、小さくなる
  • auto :コンパイラや実行時ライブラリが最適なものを決めるようにする
  • runtime :実行時にOMP_SCHEDULE環境変数を使用して決定を破棄します。実行時に環境変数が定義されていない場合は、デフォルトのスケジューリングが使用されます

scheduleのデフォルトは実装定義です。多くの環境ではstaticdynamic場合もあれば、 auto場合もあります。したがって、明示的に設定することなく、実装が暗黙的に依存しないように注意してください。

上記の例では、融合形式をparallel forまたはparallel do 。しかし、ループ構築物はでそれを融合することなく使用することができるparallelの形で、ディレクティブ#pragma omp for [...]または!$omp do [...]内のスタンドアロンディレクティブparallel地域。

Fortranバージョンの場合のみ、並列化されたループのループインデックス変数は、デフォルトでは常にprivateです。したがって、明示的にprivate宣言する必要はありません(エラーではありませんが)。
CおよびC ++バージョンでは、ループインデックスは他の変数とまったく同じです。したがって、スコープが並列化されたループの外側にある場合for ( int i = ...)ようfor ( int i = ...)宣言されていなくてint i; ... for ( i = ... )ようfor ( int i = ...)宣言されている場合は、 privateに宣言する必要があります。

Cの典型的な例

#include <stdio.h>
#include <math.h>
#include <omp.h>

#define N 1000000

int main() {
    double sum = 0;

    double tbegin = omp_get_wtime();
    #pragma omp parallel for reduction( +: sum )
    for ( int i = 0; i < N; i++ ) {
        sum += cos( i );
    }
    double wtime = omp_get_wtime() - tbegin;

    printf( "Computing %d cosines and summing them with %d threads took %fs\n",
            N, omp_get_max_threads(), wtime );

    return sum;
}

この例では、100万コサインを計算し、それらの値を並行して合計します。また、並列化がパフォーマンスに何らかの影響を与えるかどうかを確認するために、実行に移ります。最後に、時間を測定するので、コンパイラが実行した作業を最適化しないようにしなければならないので、結果を返すだけでふりをします。

Fortranでの同じ例

program typical_loop
    use omp_lib
    implicit none
    integer, parameter :: N = 1000000, kd = kind( 1.d0 )
    real( kind = kd ) :: sum, tbegin, wtime
    integer :: i

    sum = 0

    tbegin = omp_get_wtime()
    !$omp parallel do reduction( +: sum )
    do i = 1, N
        sum = sum + cos( 1.d0 * i )
    end do
    !$omp end parallel do
    wtime = omp_get_wtime() - tbegin

    print "( 'Computing ', i7, ' cosines and summing them with ', i2, &
        & ' threads took ', f6.4,'s' )", N, omp_get_max_threads(), wtime

    if ( sum > N ) then
        print *, "we only pretend using sum"
    end if
end program typical_loop

ここでもまた、100万コサインを計算して蓄積します。ループに時間を要し、不要なコンパイラの最適化を避けるために、結果を使用してふりをします。

サンプルのコンパイルと実行

GCCバージョン4.4を使用している8コアのLinuxマシンでは、Cコードをコンパイルして次のように実行できます。

$ gcc -std=c99 -O3 -fopenmp loop.c -o loopc -lm
$ OMP_NUM_THREADS=1 ./loopc
Computing 1000000 cosines and summing them with 1 threads took 0.095832s
$ OMP_NUM_THREADS=2 ./loopc
Computing 1000000 cosines and summing them with 2 threads took 0.047637s
$ OMP_NUM_THREADS=4 ./loopc
Computing 1000000 cosines and summing them with 4 threads took 0.024498s
$ OMP_NUM_THREADS=8 ./loopc
Computing 1000000 cosines and summing them with 8 threads took 0.011785s

Fortranバージョンの場合、次のようになります。

$ gfortran -O3 -fopenmp loop.f90 -o loopf
$ OMP_NUM_THREADS=1 ./loopf
Computing 1000000 cosines and summing them with  1 threads took 0.0915s
$ OMP_NUM_THREADS=2 ./loopf
Computing 1000000 cosines and summing them with  2 threads took 0.0472s
$ OMP_NUM_THREADS=4 ./loopf
Computing 1000000 cosines and summing them with  4 threads took 0.0236s
$ OMP_NUM_THREADS=8 ./loopf
Computing 1000000 cosines and summing them with  8 threads took 0.0118s

構築のためにOpenMP並列を用いた2つのベクターの追加

void parallelAddition (unsigned N, const double *A, const double *B, double *C)
{
    unsigned i;

    #pragma omp parallel for shared (A,B,C,N) private(i) schedule(static)
    for (i = 0; i < N; ++i)
    {
        C[i] = A[i] + B[i];
    }
}

この例では、2つのベクトル(追加A及びBCスレッドのチームをスポーン(で指定することによって) OMP_NUM_THREADS作業のチャンク(この例では、を介して静的に割り当てられ、例えば、environtment変数)各スレッドを割り当てるschedule(static)発現)。

private(i)オプション性に関しては備考欄を参照のこと。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow