【问题标题】:OpenMP: predetermined 'shared' for 'shared'?OpenMP:为“共享”预定“共享”?
【发布时间】:2017-09-05 02:08:16
【问题描述】:

查看这个函数(矩阵-向量积):

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 会导致相同的错误。)

【问题讨论】:

  • 我使用g++ 4.6.3编译了你的函数没有问题。
  • 我正在使用i686-apple-darwin11-llvm-gcc-4.2。这个编译器版本可能有问题。我正在尝试升级到 gcc 4.7
  • @cls:我在开玩笑。我不使用 OpenMP,所以以前从未见过这个 GCC 错误。所以你只是因为给了我一个新的 GCC 错误而获得了赞成票(你真的没有)。

标签: c++ vector openmp


【解决方案1】:

在我从 OpenMP 指令的 shared 部分删除共享的 const 变量后,我遇到了一个非常相似的问题,并且体验到可以使用 Apple 的 GCC 4.2 编译这样的程序。它们被预先确定为共享的,因为它们是恒定的,并且不需要为每个线程制作副本。而且编译器似乎只是不接受在它已经知道的时候明确地告诉它......

我还将删除default(none) 规范(但请参阅comment below)。 OpenMP 旨在减少显式规范,所以让它发挥作用吧。

【讨论】:

  • 删除default(none) 是个坏主意。如果没有default 关键字,共享策略是隐式确定的,在大多数情况下将是sharedopenmp 4.0 specification 中的第 2.14.1.1 章)。必须同步对共享成员的访问。如果没有default(none),很容易引入数据竞争而不引起注意。 default(none) 迫使您考虑如何使用会员。
【解决方案2】:

这是由于 gcc-4.2 中的 OpenMP 支持不足造成的。代码片段使用 gcc-4.7 编译没有问题。

【讨论】:

  • gcc-4.7.2 再次带来消息。解决方案是:在任何一个数据共享子句中都不必提及常量。它也适用于default(none)
猜你喜欢
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2021-08-13
  • 2012-06-14
  • 2012-07-05
相关资源
最近更新 更多