2012-05-16 13 views
7

Wenn ich den folgenden Code versuchenOpenMP Programm ist langsamer als sequenzielle ein

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); 

Ausführungszeit ca. 168 Sekunden, während die sequentielle Version verbringt nur 20 Sekunden.

Ich bin immer noch ein Neuling in der parallelen Programmierung. Wie könnte ich eine parallele Version bekommen, die schneller ist als die sequentielle Version?

Antwort

13

Der Zufallszahlengenerator rand(3) verwendet globale Statusvariablen (versteckt in der (g) libc-Implementierung). Der Zugriff auf sie aus mehreren Threads führt zu Cache-Problemen und ist auch nicht threadsicher. Sie sollten den rand_r(3) Anruf mit seed Parameter privat auf das Gewinde verwenden:

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); 
    } 
} 

Beachten Sie, dass diese unterschiedlichen Strom von Zufallszahlen, wenn parallel ausgeführt produzieren wird, als wenn in Serien ausgeführt. Ich würde auch erand48(3) als eine bessere (Pseudo-) Zufallszahlenquelle empfehlen.

+0

Es sollte auch beachtet werden, dass, da 'double x = rand()' den externen Zustand nicht ändert, der Compiler versucht sein könnte, die Schleife in der sequentiellen Version zu optimieren. Im Allgemeinen sollten Sie mit Code testen, der nicht optimiert werden kann. – Vanwaril

+2

@ Vanwaril, 'rand()' ist kein intrinsischer. Der Compiler weiß nicht, ob es eine reine Funktion ist oder nicht (es ist _nicht_) und sollte daher den Aufruf nicht optimieren. –

+0

Vielen Dank. Jetzt gibt die parallele Version 5 Sekunden aus, während die sequentielle Version 9 Sekunden benötigt. –

Verwandte Themen