2012-11-02 123 views
7

看到這個函數(矩陣,向量積):OpenMP:'共享'的預定'共享'?

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; 
} 

當試圖使用OpenMP編譯,編譯器失敗:

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 

有什麼不對嗎?

(請注意,簡單地移除const結果在相同的錯誤。)

+1

我編譯你的函數沒有問題,使用'g ++ 4.6.3'。 – Massimiliano

+0

我正在使用'i686-apple-darwin11-llvm-gcc-4.2'。這可能是這個編譯器版本的問題。我正在嘗試升級到gcc 4.7 – clstaudt

+0

@ cls:我在開玩笑。我不使用OpenMP,所以從未見過這個GCC錯誤。所以你得到了一個贊成,只是爲了給我一個新的GCC錯誤(你並不是真的)。 –

回答

0

這是通過在GCC-4.2的OpenMP支持不足引起的。代碼片段使用gcc-4.7編譯時沒有問題。

+4

gcc-4.7.2再次帶來消息。解決方案是:在任何數據共享條款中都不必提及常量。它也適用於'default(none)'。 –

4

我有一個非常類似的問題,並且經歷過這樣的程序可以使用Apple的GCC 4.2編譯後,我從OpenMP指令的shared部分刪除共享的const變量。它們被預先確定爲共享的,因爲它們是不變的,並且不需要爲每個線程製作副本。而編譯器似乎只是不接受告訴它,當它知道已經...

我也將刪除default(none)規範(但請參閱comment below)。 OpenMP旨在降低顯式規格,因此讓它能夠完成工作。

+2

刪除'default(none)'是個不錯的主意。如果沒有'default'關鍵字,共享策略是隱式確定的,在大多數情況下它將被「共享」([openmp 4.0 specification](http://www.openmp.org/mp-documents/OpenMP4)中的章節2.14.1.1。 0.0.pdf))。訪問共享成員必須進行同步。如果沒有'default(none)',很容易引入數據競賽而不會注意。 'default(none)'強制你考慮你將如何使用一個成員。 –