2016-11-22 89 views
2

我剛剛開始使用OpenMP,我需要幫助。C pragma omp並行

我有一個程序,我需要並行化它。這是我有:

#include <stdio.h> 
#include <sys/time.h> 
#include <omp.h> 

#define N1 3000000  
#define it 5 

struct timeval t0, t1; 

int i, itera_kop; 

int A[N1], B[N1]; 

void Exe_Denbora(char * pTestu, struct timeval *pt0, struct timeval *pt1) 
{ 
    double tej; 

    tej = (pt1->tv_sec - pt0->tv_sec) + (pt1->tv_usec - pt0->tv_usec)/1e6; 
    printf("%s = %10.3f ms (%d hari)\n",pTestu, tej*1000, omp_get_max_threads()); 
} 

void sum(char * pTestu, int *b, int n) 
{ 
    double bat=0; 
    int i; 

    for (i=0; i<n; i++) bat+=b[i]; 
    printf ("sum: %.1f\n",bat); 
} 

main() 
{ 
    for (itera_kop=1;itera_kop<it;itera_kop++) 
    { 
    for(i=0; i<N1; i++) 
    { 
    A[i] = 1; 
    B[i] = 3; 
    } 
    gettimeofday(&t0, 0); 
    #pragma omp parallel for private(i) 
    for(i=2; i<N1; i++) 
    { 
     A[i] = 35/(7/B[i-1] + 2/A[i]); 
     B[i] = B[i]/(A[i-1]+2) + 3/B[i]; 
    } 
    gettimeofday(&t1, 0); 
    Exe_Denbora("T1",&t0,&t1); 
    printf ("\n"); 
    } 

    printf("\n\n"); 
    sum("A",A,N1); 
    sum("B",B,N1); 

} 

如果我不使用#pragma OMP並行執行代碼,我得到:

A sum: 9000005.5 

B sum: 3000005.5 

但是,如果我嘗試並行的代碼我得到:

A sum: 9000284.0 

B sum: 3000036.0 

使用32個主題。

我想知道爲什麼我不能並行方式

+2

'A [i]'依賴於'B [i-1]'而B [i]'依賴於'A [i-1]',所以你對你的'i'迭代有依賴性'I-1'迭代。因此,您無法按原樣並行化循環。只需用'A [i]'線和'B [i]'線分割兩個循環即可。然後將兩者並行化,這應該起作用。 – Gilles

+1

爲什麼你會在全局範圍內有迭代器? – mainactual

+1

@Gilles你爲什麼不提供一個答案,你可以讓你信任它 – dreamcrash

回答

0

正如你可能知道,你的問題是在for循環的代碼。循環中的兩行之間有依賴關係。

for(i=2; i<N1; i++) 
{ 
    A[i] = 35/(7/B[i-1] + 2/A[i]); 
    B[i] = B[i]/(A[i-1]+2) + 3/B[i]; 
} 

我們無法知道任何給定線程到達這兩行中的一行的順序。因此,舉例來說,當第二行執行時,B [i]中的值將根據A [i-1]是否已被另一個線程更改而不同。 A [i]對B [i-1]值的依賴性也可以這樣說。在下面的鏈接中可以找到關於依賴關係的簡短和明確的解釋。如果這仍然不清楚,我會建議你看看。 https://scs.senecac.on.ca/~gpu621/pages/content/omp_2.html