2016-12-12 8 views
-3

I OpenMP auf einer verschachtelten Schleife bin mit derErsatz für #pragma omp kritisch (C++)

#pragma omp parallel shared(vector1) private(i,j) 
{ 
#pragma omp for schedule(dynamic) 
    for (i = 0; i < vector1.size(); ++i){ 

     //some code here 

     for (j = 0; j < vector1.size(); ++j){ 

      //some other code goes here 
     #pragma omp critical 
     A+=B; 
     } 
    C +=A; 
    } 
} 

das Problem wie dieses funktioniert hier ist, dass mein Code in der A+=B Teil eine Menge der Berechnung tut von der Code. Indem ich es kritisch mache, erreiche ich nicht die Beschleunigung, die ich möchte. (In der Tat scheint es einen gewissen Aufwand zu geben, da mein Programm länger braucht, um ausgeführt zu werden, als es sequentiell geschrieben wird).

versuchte ich

#pragma omp reduction private(B) reduction(+:A) 
    A+=B 

mit diesem beschleunigt jedoch die Ausführungszeit scheint, dass es nicht von Rennbedingungen wie die critical Klausel nicht kümmern, da ich nicht die gleichen Ergebnisse von A. bekommen

Gibt es eine Alternative zu diesem kann ich versuchen?

+3

Es gibt eine Sache, die Sie tun können: posten Sie ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve), denn mit Ihrem Pseudocode können wir nur wenig tun, um Ihnen zu helfen . – Gilles

+0

vielleicht hast du recht, aber in der Zwischenzeit kümmert sich reduction() nicht um die Rennbedingungen, oder? –

+1

Natürlich verhält es sich so, weißt du was "kritisch" und "Reduktion" macht? Sie scheinen nach dem Zufallsprinzip Ideen anzuwenden, die die Bedeutung des Programms völlig verändern. 'A' und' B' sind undefiniert, also ist es ziemlich unmöglich zu erraten, was du mit diesem Ausschnitt meinst. Es gibt kein "Pragma, das sich um Race-Bedingungen kümmert", das ist Handkurbeln, Sie sind dafür verantwortlich, den Code so zu strukturieren, dass er nicht erscheint. I.e. nichts kümmert sich darum, sie werden garantiert nicht erscheinen. – luk32

Antwort

1

Es sei denn, Sie möchten die Vector3 Klasse threadsicher machen oder Ihre Operationen für die Verwendung mit einer std::atomic<Vector3> neu schreiben, die beide immer noch unter Leistungseinbußen leiden (obwohl nicht so gravierend wie die Verwendung eines kritischen Abschnitts).

#pragma omp parallel // no need to declare variables declared outside/inside as shared/private 
{ 

    Vector3 A{}, LocalC{}; // both thread-private 

    #pragma omp for schedule(dynamic) 
    for (i = 0; i < vector1.size(); ++i){ 

     //some code here 

     for (j = 0; j < vector1.size(); ++j){ 

      //some other code goes here 

      A += B; // does not need a barrier 
     } 
     LocalC += A; // does not need a barrier 
    } 

    #pragma omp critical 
    C += LocalC; 
} 

NB, dass dies setzt voraus, dass Sie nicht A in Ihren „einige Code“ Kommentare zum Lesen zugreifen können, aber man sollte sowieso nicht, wenn Sie jemals daran gedacht, ein reduction mit:, können Sie den behaviour of OpenMP reduction nachahmen tatsächlich Klausel.

+0

Ja A wird in der äußeren Schleife gelesen (ich habe den Code gerade editiert). Jetzt, wo die Reduktionsklausel nicht verwendet werden kann, bleibt meine Frage bestehen, gibt es eine Alternative? –

+0

@ j.doe Das sehe ich nicht in deiner Frage. Möchten Sie den aktualisierten Wert wirklich lesen? Das Lesen von 'A' in einer Multithread-Situation, während andere Threads darauf schreiben, klingt wie ein Rezept für Ärger. Wenn es wirklich so ist, möchtest du es vielleicht "flüchtig" machen oder so etwas, aber ich würde gerne mehr Details darüber hören, warum du das machen willst. –

+0

Ich habe gerade die Frage 'c + = A' aktualisiert, wo A gelesen wird. vor dem 'C + = A' habe ich auch ein' #pragma omp critical. aber nur die kritische Klausel auf A scheint die Ausführungszeit zu verlangsamen, da C keine rechenintensiven Anweisungen ausführt. –

Verwandte Themen