2012-11-02 119 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)'强制你考虑你将如何使用一个成员。 –