8

次のコードを試してみると

double start = omp_get_wtime();

long i;

#pragma omp parallel for
    for (i = 0; i <= 1000000000; i++) {
        double x = rand();
    }

    double end = omp_get_wtime();

    printf("%f\n", end - start);

実行時間は約168秒ですが、シーケンシャルバージョンは20秒しかかかりません。

私はまだ並列プログラミングの初心者です。シーケンシャルバージョンよりも高速なパラレルバージョンを取得するにはどうすればよいですか?

4

1 に答える 1

15

乱数ジェネレーターrand(3)は、グローバル状態変数((g)libc実装では非表示)を使用します。複数のスレッドからそれらにアクセスすると、キャッシュの問題が発生し、スレッドセーフでもありません。スレッド専用のパラメーターを指定してrand_r(3)呼び出しを使用する必要があります。seed

long i;
unsigned seed;

#pragma omp parallel private(seed)
{
    // Initialise the random number generator with different seed in each thread
    // The following constants are chosen arbitrarily... use something more sensible
    seed = 25234 + 17*omp_get_thread_num();
    #pragma omp for
    for (i = 0; i <= 1000000000; i++) {
       double x = rand_r(&seed);
    }
}

これにより、並列で実行した場合と直列で実行した場合とで異なる乱数のストリームが生成されることに注意してください。erand48(3)また、より良い(疑似)乱数ソースとしてもお勧めします。

于 2012-05-16T19:09:11.273 に答える