【发布时间】:2017-03-22 13:43:03
【问题描述】:
我正在尝试通过减少 OpenMP 来并行化以下循环;
#define EIGEN_DONT_PARALLELIZE
#include <iostream>
#include <cmath>
#include <string>
#include <eigen3/Eigen/Dense>
#include <eigen3/Eigen/Eigenvalues>
#include <omp.h>
using namespace Eigen;
using namespace std;
VectorXd integrand(double E)
{
VectorXd answer(500000);
double f = 5.*E + 32.*E*E*E*E;
for (int j = 0; j !=50; j++)
answer[j] =j*f;
return answer;
}
int main()
{
omp_set_num_threads(4);
double start = 0.;
double end = 1.;
int n = 100;
double h = (end - start)/(2.*n);
VectorXd result(500000);
result.fill(0.);
double E = start;
result = integrand(E);
#pragma omp parallel
{
#pragma omp for nowait
for (int j = 1; j <= n; j++){
E = start + (2*j - 1.)*h;
result = result + 4.*integrand(E);
if (j != n){
E = start + 2*j*h;
result = result + 2.*integrand(E);
}
}
}
for (int i=0; i <50 ; ++i)
cout<< i+1 << " , "<< result[i] << endl;
return 0;
}
并行肯定比不并行要快,但是对于所有 4 个线程,结果变化很大。当线程数设置为 1 时,输出正确。 如果有人能帮助我解决这个问题,我将不胜感激......
我正在使用带有编译标志的 clang 编译器;
clang++-3.8 energy_integration.cpp -fopenmp=libiomp5
如果这是失败,那么我将不得不学习实现Boost::thread 或std::thread...
【问题讨论】:
-
将
firstprivate(params) reduction(+:result_int)添加到您的parallel指令中,删除critical并重试... -
@Gilles 感谢您的回复。我已经编辑了我的代码,以便第一个
#pragma语句读取#pragma omp parallel firstprivate(params) reduction(+:result_int),第二个#pragma语句保持原样,所有后续 @987654332 @ 语句被删除。然后程序会产生运行时错误:....const Eigen::Matrix<double, -1, 1, 0, -1, 1> >]: Assertion aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()' failed. Aborted- 我可以确保 kspace 和 result_int 具有相同数量的元素和维度 -
你能把你的例子完善成一个完整的minimal reproducible example吗?另外,串行版本是否按预期工作?
-
@AviGinsburg 谢谢,请参见上文,现已编辑。是的,串行版本按预期工作
-
这不完整。没有
integrand(...)的定义,您的代码也不能编译。如果串行版本返回正确的结果,您也没有回答。
标签: c++ openmp eigen clang++ eigen3