OpenMP Pi示例结果始终更改而不是3.1415

时间:2015-08-13 15:40:16

标签: c openmp

我是openMP和C的新手,我尝试过“OpenMP简介 - 蒂姆·马特森(英特尔)”Pi的例子但结果却不是3.14。我将代码与老师进行比较。他们是一样的。但结果是不同的

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

//OpenMP example program: hello;
static long num_steps = 100000;
#define NUM_THREADS 2
double step;

int main()
{
    int nnum,i,j=0;
    step= 1.0/(double)num_steps;
    double sum[NUM_THREADS];
    double x,pi,result=0.0;

    omp_set_num_threads(NUM_THREADS);

    #pragma omp parallel
    {
        int id=omp_get_thread_num();
        int num=omp_get_num_threads();
        if(id==0) nnum = num;

        for(i=id,sum[id]=0.0;i<num_steps;i=i+num)
        {       
            x=(i+0.5)*step;
            sum[id]=sum[id]+(4.0/(1.0+x*x));
        }
    }

    while(j<nnum)
    {
        printf(" is %2.4f \n",sum[j]);
        result=result+sum[j];
        j++;
    }

    pi = step*result;
    printf("the result is %f \n",pi);

    return 0;
}

1 个答案:

答案 0 :(得分:4)

代码错了。 &#34;我&#34;变量由线程共享,并且两者都递增,因此有效地只执行预期迭代的1 / NUM_THREADS。

有三种不同的方法来解决它。第一个是写

#pragma omp parallel private(i)

这使得每个线程都使用变量的单独副本。第二种是在i内声明#pragma omp parallel,这具有相同的效果(请参阅代码中id已经是私有的)。

第三个也是更有趣的是将for语句更改为

#pragma omp for 
    for(i=0;i<num_steps;i++)

这使得OpenMP编译器查看循环并说“好”,这是一个带有num_steps次迭代的循环&#34;。然后它将生成代码以将0..num_steps-1范围拆分为一个或多个块,并将它们中的每一个传递给NUM_THREADS个线程之一。例如,一个线程将处理0到49999,另一个线程将处理50000到99999.重要的是要注意:

  • 没有#pragma omp forfor循环指定每个单独线程的索引,因此迭代变量i必须是私有的

  • #pragma omp forfor循环指定整个循环的索引,迭代变量i不必是私有的,因为OpenMP将创建一个单独的线程-private迭代变量本身。