2017-10-20 3 views
0

Erstens, bedenken Sie, dass ich nicht sehr häufig Benutzer von OpenMP bin ... OK?OpenMP konditional kritisch

Jetzt, wo wir vorbei sind, gibt es so etwas wie eine bedingte critical?
Ich interessiere mich besonders für diese Linie in einem parallelisierten for Schleife:

(...) 

    #pragma omp critical 
    myMapOfVectors[i].push_back(someNumber); 

(...) 

Ich mag würde, es haben critical, wenn und nur wenn die Fäden dieses spezielle Linie haben die gleiche i läuft (weil wie ich erlebt haben - und bitte korrigieren Sie mich hier, wenn ich falsch liege - mehrere Threads, die zurück zu demselben vector schieben, ist nicht threadsicher und könnte eine segfault verursachen).

Antwort

0

Was Sie brauchen, ist eine lock für jeden Index i zu haben.

// before you parallel region 
std::vector<omp_lock_t> myLocks(myMapOfVectors.size()); 
for (size_t i = 0; i < myLocks.size(); ++i) { 
    omp_init_lock(myLocks+i); 
} 

... 

omp_set_lock(myLocks[i]); 
myMapOfVectors[i].push_back(someNumber); 
omp_unset_lock(myLocks[i]); 

... 

// after your parallel region 
for (size_t i = 0; i < myLocks.size(); ++i) { 
    omp_destroy_lock(myLocks+i); 
} 

Ein kritischer Abschnitt ist im Wesentlichen nur eine einzige Sperre, durch mehrere Schlösser mit Ihnen im Wesentlichen Emulations sind für jeden Index einen separaten kritischen Abschnitt aufweist.

Denken Sie daran, dass das Sperren sehr langsam sein kann (besonders bei Kollisionen). Sie können möglicherweise eine bessere Leistung erzielen, wenn Sie Ihre Arbeit vorzeitig partitionieren können (d. H. Jeder Thread arbeitet mit einem anderen Indexsatz i, oder jeder Thread hat seine eigene Kopie von myMapOfVectors, die später kombiniert wird).

+0

Vielen Dank für Ihre Antwort! Ich mag Ihre Lösung, aber ich würde erwarten, dass einige Richtlinien das schwere Heben für mich erledigen. Ich meine, deshalb haben wir OpenMP, nein? : P Keine Beschwerde an Sie, nur eine Kritik an OpenMP ... –

+1

Da Pragmas Kompilierzeitrichtlinien sind, können sie nicht verwendet werden, um dynamisch zugewiesene Heap-Objekte zu synchronisieren (zumindest im allgemeinen Fall). Wenn Sie ein eigenes Stack-Objekt (mit einer festen Speicherzuweisung) implementieren, können Sie '#pragma omp atomic' verwenden, um Elemente intern einzufügen (die Einfügung wäre nicht atomar, sondern würde den Zähler inkrementieren). – dlasalle