2012-11-02 11 views
7

Sehen Sie diese Funktion (Matrix-Vektor-Produkt):OpenMP: vorbestimmt "geteilt" für "geteilt"?

std::vector<double> times(std::vector<std::vector<double> > const& A, std::vector<double> const& b, int m, int n) { 

    std::vector<double> c; 
    c.resize(n); 

    int i, j; 
    double sum; 

    #pragma omp parallel for default(none) private(i, j, sum) shared(m, n, A, b, c) 
    for (i = 0; i < m; ++i) { 
     sum = 0.0; 
     for (j = 0; j < n; j++) { 
      sum += A[i][j] * b[j]; 
     } 
     c[i] = sum; 
    } 

    return c; 
} 

Beim Versuch, dies mit OpenMP zu kompilieren, der Compiler nicht mit:

Invoking: GCC C++ Compiler 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -fopenmp -MMD -MP -MF"src/OpemMPTutorial.d" -MT"src/OpemMPTutorial.d" -o "src/OpemMPTutorial.o" "../src/OpemMPTutorial.cpp" 
../src/OpemMPTutorial.cpp:127: warning: ignoring #pragma omp end 
../src/OpemMPTutorial.cpp: In function 'std::vector<double, std::allocator<double> > times(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&, std::vector<double, std::allocator<double> >&, int, int)': 
../src/OpemMPTutorial.cpp:200: error: 'b' is predetermined 'shared' for 'shared' 
../src/OpemMPTutorial.cpp:200: error: 'A' is predetermined 'shared' for 'shared' 
make: *** [src/OpemMPTutorial.o] Error 1 

Was ist hier falsch ist?

(Beachten Sie, dass nur in dem gleichen Fehler die const Ergebnisse zu entfernen.)

+1

Ich kompilierte Ihre Funktion ohne Probleme mit 'g ++ 4.6.3'. – Massimiliano

+0

Ich benutze 'i686-apple-darwin11-llvm-gcc-4.2'. Es könnte ein Problem mit dieser Compiler-Version sein. Ich versuche auf gcc 4.7 zu aktualisieren – clstaudt

+0

@cls: Ich habe Witze gemacht. Ich benutze OpenMP nicht und habe daher diesen GCC-Fehler vorher noch nie gesehen. Du hast also eine positive Bewertung bekommen, nur weil du mir einen neuen GCC-Fehler gegeben hast (du hast das nicht wirklich). –

Antwort

0

Dies wird durch unzureichende OpenMP Unterstützung in gcc-4.2 verursacht. Das Codefragment kompiliert ohne Probleme mit gcc-4.7.

+4

gcc-4.7.2 bringt die Nachricht erneut. Die Lösung ist: Konstanten müssen in keiner der Datenfreigabeklauseln erwähnt werden. Es funktioniert auch mit 'default (none)'. –

4

Ich hatte ein sehr ähnliches Problem und erfuhr, dass ein solches Programm mit Apples GCC 4.2 kompiliert werden kann, nachdem ich die gemeinsamen const Variablen aus dem shared Abschnitt der OpenMP-Richtlinie entfernt habe. Sie sind als gemeinsam festgelegt, da sie konstant sind und keine Kopie für jeden Thread erstellt werden muss. Und der Compiler scheint es einfach nicht zu akzeptieren, es explizit zu sagen, wenn es bereits weiß ...

Ich würde auch die default(none) Spezifikation entfernen (aber siehe comment below). OpenMP soll explizite Spezifikationen reduzieren, also lassen Sie es seine Arbeit machen.

+2

Es ist eine schlechte Idee, 'default (none)' zu entfernen. Ohne das Schlüsselwort 'default' wird implizit die Sharing-Strategie festgelegt, die in den meisten Fällen" geteilt "wird (Kapitel 2.14.1.1 in [openmp 4.0 specification] (http://www.openmp.org/mp-documents/OpenMP4). 0.0.pdf)). Der Zugriff auf freigegebene Mitglieder muss synchronisiert werden. Ohne 'default (none)' ist es einfach Datenrennen vorzustellen, ohne es zu merken. 'default (none)' zwingt Sie dazu, darüber nachzudenken, wie Sie ein Mitglied verwenden werden. –