Frage von Krypton89, 38

Paralleles Programmieren mit OpenMP in C Langsamer?

Guten Tag, Ich habe eine Frage bezüglich Paralleles Programmieren in C. Mein Code arbeitet sequentiell viel schneller, als parallel. Woran liegt das? Ich habe einen sehr einfachen Code geschrieben, damit ich erstmal den Grundsatz lerne.

Hier der Code:

#include <stdio.h>
#include <omp.h>
#define B 2000000000
#define NUM_THREADS 4
void main(){

    long n = 0;
    int i = 0;
    double start = omp_get_wtime();
    double zeit = 0;
    double end = 0;
    omp_set_num_threads(NUM_THREADS);

    #pragma omp parallel for
    for(i=0;i<B;i++){
        n++;
    }
    end = omp_get_wtime();
    zeit = end-start;
    printf("Laufzeit = %lf  ms\n",zeit*1000);
    printf("N = %ld \n",n); 
}

Ich habe auch schon mit atomic etc. rumgespielt, aber der Code wird einfach immer langsamer.

Antwort
von Mikkey, 25

Da bist Du schon mal in die erste Falle getappt:

n++

Wie, denkst Du sollte so etwas parallel ausgeführt werden. Jeder Thread muss vor Beginn der Anweisung die Variable für die anderen Threads sperren und sie erst nach der Anweisung wieder freigeben. Dieser Overhead ist um ein Vielfaches aufwendiger als das einen einzelnen Prozessor machen zu lassen.

OpenMP kenne ich nicht, aber Multithreading i.S. von Task-Verteilung.

Expertenantwort
von TeeTier, Community-Experte für programmieren, 2

Erst mal muss dir klar sein, dass der Compiler die GESAMTE Schleife wegoptimieren, und durch "n = 2000000000;" ersetzen wird. Danach bleibt also schon gar nichts mehr übrig, was sich irgendwie parallelisieren lassen würde, da es sich nur um eine einzige (atomare) CPU-Instruktion handeln wird.

Da das sowohl für die "parallele" als auch die sequentielle Variante gilt, ist der Overhead für Threaderstellung, Kontextwechsel und Zusammenführung verglichen mit einer einfachen Zuweisung (siehe erster Absatz) mit Sicherheit einige tausend (wenn nicht gar hunderttausend) mal langsamer!

Darüber hinaus gilt all das, was die anderen in ihren Antworten bereits geschrieben haben.

Trotzdem noch viel Erfolg! :)

Antwort
von DoTheBounce, 5

Der von dir geschriebene Code ist - so wie du ihn geschrieben hast - nicht vernünftig parallelisierbar. n ist eine Variable, die bei allen Threads gleich sein muss, damit entsteht overhead zur Synchronisation.

Antwort
von Nube4618, 26

Ev. werden parallele Prozesse als eigene Tasks instanziert? Da kämen dann immer noch die Taskswitch-Zeiten dazu, und wenn dem so wäre, müsste man dem Task eine Priorität zuweisen können, sonst bekommt er ev. zu kleine Zeitscheiben.  

Keine Ahnung ob das jetzt wirklich der Grund ist, doch wäre immerhin möglich.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten