[英]OpenMP Pi example outcome always changes rather than 3.1415
我是openMP和C的新手,我嘗試了“ OpenMP簡介-Tim Mattson(Intel)” 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;
}
代碼錯誤。 線程共享“ i”變量,並且兩個變量都對其進行遞增,因此實際上,您只執行了預期迭代的1 / NUM_THREADS個。
有三種不同的修復方法。 首先是寫
#pragma omp parallel private(i)
這使得每個線程使用變量的單獨副本。 第二個方法是在#pragma omp parallel
內部聲明i
,這具有相同的效果(請參閱id
在您的代碼中如何是私有的)。
第三個也是更有趣的是將for
語句更改for
#pragma omp for
for(i=0;i<num_steps;i++)
這使OpenMP編譯器查看循環並說“好的,這是一個具有num_steps
次迭代的循環”。 然后,它將生成代碼以將0..num_steps-1范圍划分為一個或多個塊,並將每個塊傳遞給NUM_THREADS
線程之一。 例如,一個線程將處理0到49999,另一個線程將處理50000到99999。重要的是要注意:
如果沒有#pragma omp for
,則for
循環將為每個單獨的線程指定索引,因此迭代變量i
必須是私有的
使用#pragma omp for
, for
循環指定整個循環的索引,並且迭代變量i
不必是私有的,因為OpenMP會自己創建一個單獨的線程私有的迭代變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.