2012-09-04 11 views
7

Unterstützt OpenMP ein atomisches Minimum für C++ 11? Wenn OpenMP keine portable Methode hat: Gibt es eine Möglichkeit, dies mit einer x86- oder amd64-Funktion zu tun?Atom Minimum auf x86 mit OpenMP

In den OpenMP-Spezifikationen habe ich nichts für C++ gefunden, aber die Fortran-Version scheint es zu unterstützen. Siehe 2.8.5 der v3.1 für die Details. Für C++ heißt es

binop ist eine von +, *, -, /, &, ^, |, < < oder >>.

aber für Fortran heißt es

intrinsic_procedure_name eines von MAX, MIN ist, IAND, IOR oder IEOR.

Falls Sie in mehr Kontext interessiert: Ich bin auf der Suche nach einem Mutex frei Verfahren zur Herstellung der folgenden Aktionen ausführen:

vector<omp_lock_t>lock; 
vector<int>val; 

#pragma omp parallel 
{ 
    // ... 
    int x = ...; 
    int y = ...; 
    if(y < val[x]){ 
    omp_set_lock(&lock[x]); 
    if(y < val[x]) 
     val[x] = y; 
    omp_unset_lock(&lock[x]); 
    } 
} 

Ich weiß, dass Sie das Minimum berechnen kann ein Algorithmus reduzieren verwenden. Ich weiß, dass es Umstände gibt, in denen dies einen atomaren Minimalansatz weit übertrifft. Ich weiß aber auch, dass dies in meiner Situation nicht der Fall ist.

EDIT: Eine Option, die etwas schneller in meinem Fall ist

int x = ...; 
    int y = ...; 
    while(y < val[x]) 
    val[x] = y; 

aber das ist keine atomare Operation.

Alle neueren GPUs haben diese Funktion und ich vermisse es auf der CPU. (Siehe atom_min für OpenCL.)

+0

Ist das C++ 98 oder C++ 11? – user1071136

+0

C++ 11 Antworten sind ok –

+0

Übrigens, warum ist Atom-Min in Ihrem Fall schneller? Ich hatte ein ähnliches Problem, bei dem Reduktion-min die Leistung nicht verbesserte, also sollte ich vielleicht atomic-min ausprobieren. – user1071136

Antwort

4

Die OpenMP-Spezifikation für C++ unterstützt nicht das atomare Minimum. Weder tut C++ 11.

Ich gehe davon aus, dass in Ihrem Algorithmus, x zu jedem gültigen Index, unabhängig von Thread berechnen kann. Ich würde vorschlagen, Ihren Algorithmus zu ändern, so dass jeder Thread sein eigenes val Array verwendet und dann eine endgültige Abstimmung am Ende, die auch durch Index parallelisiert werden kann. Dies wird Sperren und Atomics vollständig vermeiden und Ihnen den Vorteil geben, die Daten für jeden Thread zu trennen, d. H. Keine Chance für eine falsche Cache-Aufteilung. Mit anderen Worten, es sollte schneller sein.