2016-04-30 14 views
1

I recently learned wie die Methode eines Objekts zu einer Funktion für die Auswertung übergeben werden und jetzt möchte ich OpenMP in einer Schleife verwenden, während diese Methode aufrufen. Der eigentliche Code ist:Verwenden von OpenMP beim Aufruf mit einem Zeiger auf eine Methode

std::vector< std::vector<double> > grid2D(wfn& W, double (wfn::*p)(double, double, double), std::vector<double> xs, std::vector<double> ys, double z) { 
    std::vector< std::vector<double> > fs; 
    int nx = (int)xs.size(); 
    int ny = (int)ys.size(); 

    fs.resize(nx); 
    for(int ix = 0; ix < nx; ix++) { 
     fs[ix].resize(ny); 
     for(int iy = 0; iy < ny; iy++) { 
      fs[ix][iy] = (W.*p)(xs[ix], ys[iy], z); 
     } 
    } 

    return fs; 
} 

wo wfn die „Wellenfunktion“ eines Moleküls darstellt und viele, viele private Variablen gespeichert, um die Physik zu repräsentieren.

Wenn ich #pragma omp parallel for über die Schleife über iy einfügen, ist die Rastergenerierung von fs[ix][iy] falsch. Gibt es eine Möglichkeit W.*p als privat an diese #pragma zu übergeben, so dass die Auswertung von Threadssafe ist?

+1

Ist p eine 'const' Methode? Kannst du "W" als "const" übergeben? Wenn nicht, was passiert mit dem Zustand von "W" innerhalb von "p"? – Zulan

Antwort

0

Sie geben nicht viel Details über die genaue # pragma omp-Anweisung, die Sie vor der zweiten for-Schleife einfügen. Ich nehme an, dass Sie keine Variable als privat deklarieren, daher werden alle Variablen innerhalb der Schleife als gemeinsam genutzt angenommen. Dies führt zu Threads, die Daten auf unvorhersehbare Weise ändern. Sie können Variablen als privat deklarieren, indem Sie der Anweisung private (list_of_variables) hinzufügen. Möglicherweise möchten Sie mit dem Hinzufügen von "default (none)" (ohne Anführungszeichen) zu der # pragma omp-Anweisung beginnen und alle Variablen als privat deklarieren. Dann können Sie beginnen, einzelne Variablen aus der Liste zu entfernen und sie als gemeinsam zu deklarieren. Natürlich müssen Sie nach jeder Änderung Ihren Code erneut kompilieren und ausführen. Manchmal dauert dieser Prozess eine Weile, um es richtig zu machen. So können Sie mit

#pragma omp parallel zur Standard (keine) starten privat (W, xs, ys, iy, fs, z) firstprivate (ix)

Je nach Version von OMP Sie verwenden, Die Schleifenvariable iy kann standardmäßig privat sein.