【问题标题】:Why do I get undefined behavior when using OpenMP's firstprivate with std::vector on Intel compiler?为什么在英特尔编译器上使用 OpenMP 的 firstprivate 和 std::vector 时会出现未定义的行为?
【发布时间】:2014-05-21 07:26:19
【问题描述】:

在英特尔 c++ 编译器上将 OpenMP 与 firstprivate 和 std::vector 结合使用时出现问题。取以下三个函数:

#include <omp.h>

void pass_vector_by_value(std::vector<double> p) {
#pragma omp parallel
{
    //do sth
}
}

void pass_vector_by_value_and_use_firstprivate(std::vector<double> p) {
#pragma omp parallel firstprivate(p)
{
    //do sth
}
}

void create_vector_locally_and_use_firstprivate() {
std::vector<double> p(3, 7);
#pragma omp parallel firstprivate(p)
{
    //do sth
}
}

代码编译时没有警告:

icc filename.cpp -openmp -Wall -pedantic

(icc 14.0.1版(gcc 4.7.0版兼容性))

或:

g++ filename.cpp -fopenmp -Wall -pedantic

(gcc 版本 4.7.2 20130108 [gcc-4_7-branch 修订版 195012] (SUSE Linux))

但在使用 icc 编译后,我遇到了运行时错误,例如:

*** Error in `./a.out': munmap_chunk(): invalid pointer: 0x00007fff31bcc980 ***

调用第二个函数时(pass_vector_by_value_and_use_firstprivate)

因此,只有在使用 firstprivate 子句(应该调用复制构造函数)并且向量按值传递给函数(也应该调用复制构造函数)时才会发生错误。当不传递向量但在函数中本地创建它或不使用 firstprivate 时,没有错误!在 gcc 上我没有收到任何错误。

我想知道代码是否会以某种方式产生未定义的行为,或者这是否是 icc 中的错误?

【问题讨论】:

  • 这是一个编译器错误。在对该问题的已删除答案中,一位英特尔工程师复制了该错误并与英特尔工程团队一起升级。希望事情现在得到解决。

标签: c++ gcc vector openmp icc


【解决方案1】:

我在 ICC 上遇到了同样的问题,但在 GCC 上没有。看起来像一个错误。这是一个解决方法

void pass_vector_by_value2(std::vector<double> p) {
    #pragma omp parallel
    {
        std::vector<double> p_private = p;
        //do sth with p_private      
    }
}

另一方面,总的来说,我不会将非 POD 按值传递给函数。我会使用参考,但如果你这样做,你会得到错误

error: ‘p’ has reference type for ‘firstprivate’

解决方案是我在上面发布的代码。通过值或引用传递它,然后在并行区域内定义一个私有副本,就像我在上面的代码中所做的那样。

【讨论】:

  • 是的,这正是我之前所做的,但现在我想使用 firstprivate 让它更干净。很高兴知道您可以重现该错误,我可能会在英特尔论坛上发布错误报告。根据 openmp 规范 firstprivate 不接受引用,因此您描述的错误。在这种特殊情况下,我认为按值传递向量是有意义的,因为每个线程都会复制向量(通过显式复制或使用 firstprivate)。
猜你喜欢
  • 2018-10-17
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多