2016-11-22 87 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