使用OpenMP C++并行化程序计算积分

4

我正在尝试计算积分

#include <iostream>
#include <omp.h>

using namespace std;

double my_exp(double x) {
  double res = 1., term = 1.;
  for(int n=1; n<=1000; n++) {
    term *= x / n;
    res += term;
  }
  return res;
}

double f(double x) {
  return x*my_exp(x);
}


int main() {
  double a=0., b=1., result = 0.;
  int nsteps = 1000000;
  double h = (b - a)/nsteps;


  for(int i=1; i<nsteps; i++) result += f(a + i*h);
  result = (result + .5*(f(a) + f(b)))*h;

  cout.precision(15);
  cout << "Result: " << result << endl;
  return 0;
}

这个程序计算整数并返回结果 Result: 1.00000000000035。但是执行时间很长。 我应该让我的程序并行化,我想我应该添加 #pragma omp parallel for,但它不起作用。


我建议您使用g++。您是否使用“-fopenmp”编译它了? - muXXmit2X
是的,我使用 g++。我尝试了 -fopenmp,但它并没有改变程序执行时间。我应该修改我的代码,但我从未使用过 openmp - Arseniy Krupenin
1个回答

1
更改您的主要函数。
#pragma omp parallel 
  {
  double localresult = 0.0;
#pragma omp for
  for(int i=1; i<nsteps; i++) 
      localresult +=  f(a + i*h);
#pragma omp critical
  {
      result += localresult;
  }
  }

  result = (result + .5*(f(a) + f(b)))*h;

编辑:按照muXXmit2X的思路,更简单的解决方案是:

#pragma omp parallel for reduction(+:result)
for(int i=1; i<nsteps; i++) result += f(a + i*h);

result = (result + .5*(f(a) + f(b)))*h;

3
声明reduction(+: result)比使用本地变量进行约简更简单,另外还要添加一个带有critical的额外步骤。 - Gilles
真的。风格不好。我在之前的一篇评论中建议过,但现在似乎已经被删除了...无论如何,还是发出来吧... - Mohammed Li
我认为这是不正确的,因为程序执行的时间应该要少得多。但是在我的代码中,它仍然是9秒。 - Arseniy Krupenin
不对。你做错了什么。目前在Windows上,你的本地代码需要6158.88毫秒,缩减变量需要1725.02毫秒,局部变量需要1788.51毫秒。进程数量设置为4。请再次检查你的代码,并确保设置了OMP_NUM_THREADS变量。 - Mohammed Li

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接