2017-08-14 107 views
0

我是一個新的OpenMp Programer,現在我遇到了乘以兩個矩陣的問題。這是我的並行代碼,但速度並不像我想象的那麼快。 例如我給它一個3000 * 3000矩陣和3000 * 3000和我的域爲2(隨機數爲0或1)和並行慢於順序並行乘法矩陣openmp比序列更慢

clock_t tStart = clock(); 
    cout<<(char)169<<" parallel "<<(char)170<<endl; 
    int a,b,c,Domain ; 
    cin>>a>>b>>c>>Domain; 
    srand(time(0)); 
    int **arr1; 
    int **arr2; 
    int **arrRet; 

    arr1 = new int*[a]; 
    #pragma omp for schedule (dynamic) 
    for(int i=0 ; i<a ; i++) 
    arr1[i] = new int [b]; 

    arr2 = new int*[b]; 
    #pragma omp for schedule (dynamic) 
    for(int i=0 ; i<b ; i++) 
    arr2[i] = new int [c]; 

    arrRet = new int*[a]; 
    #pragma omp for schedule (dynamic) 
    for(int i=0 ; i<a ; i++) 
    arrRet[i] = new int [c]; 

    #pragma omp for schedule (dynamic) 
    for(int i=0 ; i<a ; i++) 
    { 
     #pragma omp for schedule (dynamic) 
     for(int j=0; j<b ; j++) 
     { 
     arr1[i][j]=rand()%Domain; 
     } 
    } 

    //cout<<"\n\n\n"; 
    #pragma omp for schedule (dynamic) 
    for(int i=0 ; i<b ; i++) 
    { 
     #pragma omp for schedule (dynamic) 
     for(int j=0 ; j<c ; j++) 
     { 
     arr2[i][j]=rand()%Domain; 
     } 
    } 

    //cout<<"\n\n\n"; 
    #pragma omp for schedule (dynamic) 
    for(int i=0 ; i<a ; i++) 
     #pragma omp for schedule (dynamic) 
     for(int j2=0 ; j2<c ; j2++) 
     { 
      int sum=0; 
      #pragma omp parallel for shared(sum) reduction(+:sum) 
      for(int j=0 ; j<b ; j++) 
      { 
       sum+=arr1[i][j]*arr2[j][j2]; 
      } 
      arrRet[i][j2]=sum; 
     } 
    printf("Time taken : %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC); 
+1

的可能的複製[OpenMP的時間和時鐘()計算兩個不同的結果](HTTPS:/ /stackoverflow.com/questions/10673732/openmp-time-and-clock-calculates-two-different-results)和https://stackoverflow.com/q/10624755/620382 – Zulan

+1

不要自己做矩陣乘法。這太瘋狂了。矩陣乘法是本書中最古老的問題。找一些圖書館爲你做這些,比如OpenBLAS。也可以使用[Armadillo](http://arma.sourceforge.net/)來保存矩陣。停止保留這些不良陣列以保存矩陣。它們很慢,因爲你的編譯器不能[矢量化](https://en.wikipedia.org/wiki/Automatic_vectorization)它們。您可以將Armadillo與OpenBLAS連接起來,它可以爲您和您的處理器功能進行並行處理,從而爲您提供最佳性能。 –

+0

@TheQuantumPhysicist我的老師告訴我我不能使用庫:( – ali

回答

0

有許多高度優化linear algebra libraries是免費使用。我強烈建議你儘可能使用其中之一。

您的性能下降可能由許多原因產生。下面詳細列舉了一些最常見的原因:

  • 使用schedule(dynamic)時每次迭代的工作量是完全平衡。省略該子句將把時間表設置爲static,這對於此類並行化更爲合適。

  • 內存分配壓力過大。您實際上並不需要爲單個矩陣保留多個內存區域。由於您的程序中矩陣大小不會改變,因此您可以完美地爲每個矩陣使用一次分配。這也改善了數據的局部性,因爲連續的行在內存中彼此接近。然後,您可以使用A[ i * b + j ]訪問每個元素,其中b是列數。

int *A = (int *) malloc(a * b * sizeof(int)); 
  • 在代碼中,你似乎已經錯過了parallel區域。這會導致除最後一個之外的所有omp for都不會被多個線程執行。

  • 使用collapse(2)如下面的示例合併廣告omp for構建體在嵌套循環:

#pragma omp for collapse(2) 
for(i = 0; i < a; i++) { 
    for(j = 0; j < b; j++) { 
     // your parallel code 
    } 
}