2017-02-23 40 views
2

我有一個程序可以分爲幾個彼此沒有數據依賴關係的部分。我想在使用OpenMP的處理器的不同內核上運行這些部件。我已經嘗試了下面的代碼,但單核上的執行時間要少於多核上的執行時間。你能告訴我我哪裏出錯了嗎?使用OpenMP在不同內核上運行代碼的不同部分

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

     void serial(){ 

      unsigned int a[10],b[10],c[10]; 
      long long int i,j,k; 
      for(i=0;i<10;i++){ 
       b[i]=rand(); 
       c[i]=rand(); 
      } 

      a[0]=b[0]-c[0]; 
      a[1]=b[1]*c[1]; 
      a[2]=b[2]^c[2]; 
      a[3]=b[3]|c[3]; 
      a[4]=(b[4]*5)+c[4]; 
      a[5]=(!b[5])&c[5]; 
      a[6]=b[6]+c[6]; 
      a[7]=b[7]-c[7]; 
      a[8]=b[8]&c[8]; 
      a[9]=b[9]^c[9]; 

      for(i=0;i<10;i++){ 
       printf("a[%lld]=%u\t",i,a[i]); 
      } 
     } 

     void parallel(){ 

      unsigned int a[10],b[10],c[10]; 
      int num_thread; 
      long long int i,j,k; 
      for(i=0;i<10;i++){ 
       b[i]=rand(); 
       c[i]=rand(); 
      } 
      #pragma omp parallel 
      { 
      int ID; 
      long long int i1; 
      ID=omp_get_thread_num(); 
      if(ID==0){ 
       printf("ID is %d\n",ID); 
       a[0]=b[0]-c[0]; 
       a[1]=b[1]*c[1]; 
       a[2]=b[2]^c[2]; 
       a[3]=b[3]|c[3]; 
       a[4]=(b[4]*5)+c[4]; 
       } 
      else{ 
       printf("ID is %d\n",ID); 
       a[5]=(!b[5])&c[5]; 
       a[6]=b[6]+c[6]; 
       a[7]=b[7]-c[7]; 
       a[8]=b[8]&c[8]; 
       a[9]=b[9]^c[9];     
       } 
      } 
      for(i=0;i<10;i++){ 
       printf("a[%lld]=%u\t",i,a[i]); 
      } 
     } 



     void main(){ 

      double time; 
      unsigned long long int clock1,clock2; 

      time=omp_get_wtime(); 
      serial(); 
      time=omp_get_wtime()-time; 
      printf("\nSerial time : %f \n",time); 

      time=omp_get_wtime(); 
      parallel(); 
      time=omp_get_wtime()-time; 
      printf("\nParallel time : %f\n",time); 

     } 

當我運行上面的代碼時,並行程序所需要的時間比串行程序多4倍。 EDIT#1更新了代碼

  #include<stdio.h> 
      #include<stdlib.h> 
      #include<omp.h> 
      unsigned long long int N=1000; 
      unsigned long long int *a1,*b1,*c1,*d1; 
      void init(){ //just to put some random data 

       unsigned long long int i; 
       a1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int)); 
       b1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int)); 
       c1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int)); 
       d1=(unsigned long long int *)malloc(N*sizeof(unsigned long long int)); 
       for(i=0;i<N;i++){ 
        a1[i]=rand(); 
        b1[i]=rand(); 
        c1[i]=rand(); 
        d1[i]=rand(); 
       } 
      } 
      void seq(){//runs on one core 

       unsigned long long int i; 
       unsigned long long int a[N],b[N],c[N],d[N]; 

       for(i=0;i<N;i++){ 
        a[i]=a1[i]; 
        b[i]=b1[i]; 
        c[i]=c1[i]; 
        d[i]=d1[i]; 
       } 

       for(i=0;i<N;i++){ 
        a[i]=a[i]+b[i]; 
       } 

       for(i=0;i<N;i++){ 
        c[i]=c[i]+d[i]; 
       } 

      } 
      void parallel(){//runs on 2 cores 

       unsigned long long int i; 
       unsigned long long int a[N],b[N],c[N],d[N]; 

       for(i=0;i<N;i++){ 
        a[i]=a1[i]; 
        b[i]=b1[i]; 
        c[i]=c1[i]; 
        d[i]=d1[i]; 
       } 
       #pragma omp parallel 
       { 
        int ID; 
        ID=omp_get_thread_num(); 
        if(ID==0){ 
         for(i=0;i<N;i++){ 
          a[i]=a[i]+b[i]; 
         } 
        } 
        else{ 
         for(i=0;i<N;i++){ 
          c[i]=c[i]+d[i]; 
         } 
        } 
       } 
      } 

      void main(){ 

       init(); 
       double time; 

       time=omp_get_wtime(); 
       seq(); 
       time=omp_get_wtime()-time; 
       printf("\n time for serial execution : %f\n",time); 

       time=omp_get_wtime(); 
       parallel(); 
       time=omp_get_wtime()-time; 
       printf("\ntime for parallel execution : %f\n",time); 
      } 

儘管如此並行比串行執行兩次慢。該程序在intel core2處理器上運行。

+3

即使線程之間沒有數據依賴關係,也存在與並行相關的開銷。除了所有其他的考慮因素,你提出的計算是非常短的;如果並行化的任何收益在這種情況下沒有被克服,我真的會感到驚訝。 –

+0

感謝您的回覆。這不是我的實際問題,我把它放在這裏是爲了說明。我會更新代碼。 – Rick

+0

爲什麼不使用'#pragma omp parallel for',你在哪裏指定它應該創建多少個線程?如果你反覆做3個線程的第二部分,則需要更長的時間。無論如何你的實際時間是多少? –

回答

1

您正在運行的操作(只是'+')太簡單了,無法獲得並行化的優勢,因爲omp的額外開銷也很重要。 試了一下更復雜的操作:

for(i=0;i<N;i++){ 
    a[ i ] = sqrtf(a[ i ] + b[ i ]); 
} 

for(i=0;i<N;i++){ 
    c[ i ] = sqrtf(c[ i ] + d[ i ]); 
} 

而且你必須在平行()函數的非並行initalization循環。更好地初始化你的A和B的在並行for循環,太:

if(ID==0) 
    { 
     for(int i=0;i<N;i++) 
     { 
      a[ i ] = a1[ i ]; 
      b[ i ] = b1[ i ]; 
      a[ i ] = sqrtf(a[ i ] + b[ i ]); 
     } 
    } 
    else 
    { 
     for(int i=0;i<N;i++) 
     { 
      c[ i ] = c1[ i ]; 
      d[ i ] = d1[ i ]; 
      c[ i ] = sqrtf(c[ i ] + d[ i ]); 
     } 
    } 
} 

當然,這將是更好地使用A1,B1,C1和D1直接...。

相關問題