0

私が探しているのは、並列 for ループからすべてのデータを 1 つの変数に収集する最良の方法は何かということです。OpenMP には、スキャッター ルーチンとギャザー ルーチンを持つ OpenMPI を最初に学習し始めたときに見慣れているものとは異なるルーチンがあるようです。

PI の計算 (恥ずかしい並列ルーチン)

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

#define NUM_STEPS 100
#define CHUNKSIZE 20

int main(int argc, char *argv[])
{
    double step, x, pi, sum=0.0;
    int i, chunk;

    chunk = CHUNKSIZE;
    step = 1.0/(double)NUM_STEPS;

    #pragma omp parallel shared(chunk) private(i,x,sum,step)
    {

        #pragma omp for schedule(dynamic,chunk)
            for(i = 0; i < NUM_STEPS; i++)
            {
                x = (i+0.5)*step;
                sum = sum + 4.0/(1.0+x*x);
                printf("Thread %d: i = %i sum = %f \n",tid,i,sum);
            }
        pi = step * sum;
    }

編集: 配列 sum[*NUM_STEPS / CHUNKSIZE*] を使用して、配列を 1 つの値に合計するか、何らかのブロッキング ルーチンを使用して各反復の積を合計する方がよいようです

4

2 に答える 2

2

次の句を#pragma omp parallel ...ステートメントに追加します。

reduction(+ : pi) 

次にpi += step * sum;、並列領域の最後で実行します。(プラスに注意してください!) OpenMP は部分的な合計を自動的に合計します。

于 2013-05-24T20:44:21.123 に答える
1

完成したアプリケーションで決定論的な動作が得られていないため、どうなるかはよくわかりませんが、πに似たものがあります。を削除し、#pragma omp parallel shared(chunk)に変更し#pragma omp for schedule(dynamic,chunk)ました#pragma omp parallel for schedule(dynamic) reduction(+:sum)

#pragma omp parallel for schedule(dynamic) reduction(+:sum)

scheduleこれにはいくつかの説明が必要です。(私にとっては)簡単にするために s チャンクを削除しました。あなたが興味を持っている部分は、オペレーターと変数を使用しreduction(+:sum)た通常のreduce操作です。+sum

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

#define NUM_STEPS 100

int main(int argc, char *argv[])
{
    double step, x, pi, sum=0.0;
    int i;

    step = 1.0/(double)NUM_STEPS;

#pragma omp parallel for schedule(dynamic) reduction(+:sum)
    for(i = 0; i < NUM_STEPS; i++)
    {
        x = (i+0.5)*step;
        sum +=4.0/(1.0+x*x);
        printf("Thread %%d: i = %i sum = %f \n",i,sum);
    }
    pi = step * sum;
    printf("pi=%lf\n", pi);
}
于 2013-05-24T20:52:25.127 に答える