我正在尝试使用 openMP 在 C++ 中通过多线程计算 4/(1+x^2) 从 0 到 1 的积分。 我拿了一个串行程序(这是正确的)并进行了更改。 我的想法是: 假设 X 是线程数。 把函数下面的区域分成X份,先从0到1/X,1/X到2/X…… 每个线程都会计算它的面积,我会总结一下。
我是这样实现的:
`//N.o. of threads to do the task
cout<<"Enter num of threads"<<endl;
int num_threads;
cin>>num_threads;
int i; double x,pi,sum=0.0;
step=1.0/(double)num_steps;
int steps_for_thread=num_steps/num_threads;
cout<<"Steps for thread : "<<steps_for_thread<<endl;
//Split to threads
omp_set_num_threads(num_threads);
#pragma omp parallel
{
int thread_id = omp_get_thread_num();
thread_id++;
if (thread_id == 1)
{
double sum1=0.0;
double x1;
for(i=0;i<num_steps/num_threads;i++)
{
x1=(i+0.5)*step;
sum1 = sum1+4.0/(1.0+x1*x1);
}
sum+=sum1;
}
else
{
double sum2=0.0;
double x2;
for(i=num_steps/thread_id;i<num_steps/(num_threads-thread_id+1);i++)
{
x2=(i+0.5)*step;
sum2 = sum2+4.0/(1.0+x2*x2);
}
sum+=sum2;
}
} '
解释: 第 i 个线程将计算 i/n 到 (i+1)/n 之间的面积并将其添加到总和中。
问题是不仅输出错误,而且每次运行程序时我都会得到不同的输出。
欢迎任何帮助 谢谢
最佳答案
你让这个问题变得比它需要的更难。 OpenMP 的目标之一是不必更改串行代码。您通常只需要添加一些 pragma 语句。所以你应该先写串口方法。
#include <stdio.h>
double pi(int n) {
int i;
double dx, sum, x;
dx = 1.0/n;
#pragma omp parallel for reduction(+:sum) private(x)
for(i=0; i<n; i++) {
x = i*dx;
sum += 1.0/(1+x*x);
}
sum *= 4.0/n;
return sum;
}
int main(void) {
printf("%f\n",pi(100000000));
}
输出:3.141593
请注意,在函数 pi
中,串行代码和并行版本之间的唯一区别是语句
#pragma omp parallel for reduction(+:sum) private(x)
您通常也不应该担心设置线程数。
关于c++ - 使用 openMP 的并行程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26382714/