簡體   English   中英

OpenMP Pi示例結果總是更改,而不是3.1415

[英]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 forfor循環指定整個循環的索引,並且迭代變量i不必是私有的,因為OpenMP會自己創建一個單獨的線程私有的迭代變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM