在英特尔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 revision 195012](SUSE Linux))
但在使用icc进行编译后,我遇到运行时错误,例如:
*** Error in `./a.out': munmap_chunk(): invalid pointer: 0x00007fff31bcc980 ***
调用第二个函数时(pass_vector_by_value_and_use_firstprivate)
因此,只有在使用firstprivate子句(应该调用复制构造函数)并且向量通过值传递给函数(也应该调用复制构造函数)时才会出现错误。当没有传递向量但在函数中本地创建它或不使用firstprivate时,没有错误!在gcc上我没有任何错误。
我想知道代码是否会以某种方式产生未定义的行为,或者这是否是icc中的错误?
答案 0 :(得分:1)
我遇到了与ICC相同的问题,但没有GCC。看起来像个bug。这是一个解决方法
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’
解决方法就是我上面发布的代码。按值或通过引用传递它,然后像在上面的代码中那样在并行区域内定义私有副本。