2016-08-17 73 views
0

我在OpenMP任務中遇到問題。我正在嘗試使用omp任務爲「for」循環創建並行版本。但是,執行此版本的時間比基本版本長2倍,我使用omp,因此我不知道這是什麼原因。看看代碼波紋管:OpenMP任務並行 - 性能問題

OMP的版本:

t.start(); 
#pragma omp parallel num_threads(threadsNumber) 
{ 
    for(int ts=0; ts<1000; ++ts) 
    { 
     #pragma omp for 
     for(int i=0; i<size; ++i) 
     { 
      array_31[i] = array_11[i] * array_21[i]; 
     } 
    } 
} 
t.stop(); 
cout << "Time of omp for: " << t.time() << endl; 

OMP任務版本:

t.start(); 
#pragma omp parallel num_threads(threadsNumber) 
{ 
    #pragma omp master 
    { 
     for(int ts=0; ts<1000; ++ts) 
     { 
      for(int th=0; th<threadsNumber; ++th) 
      { 
       #pragma omp task 
       { 
        for(int i=th*blockSize; i<th*blockSize+blockSize; ++i) 
        { 
         array_32[i] = array_12[i] * array_22[i]; 
        } 
       }      
      } 

      #pragma omp taskwait 
     } 
    } 
} 
t.stop(); 
cout << "Time of omp task: " << t.time() << endl; 

在任務的版本我把同樣的方式循環在OMP的。每個任務都必須執行相同數量的迭代。總任務量等於線程總量。

性能測試結果:

Time of omp for: 4.54871 
Time of omp task: 8.43251 

什麼可能是一個問題?兩種版本都可以達到相似的性能嗎?附加代碼很簡單,因爲我只想說明我的問題,我試圖解決。我不認爲這兩個版本都會給我同樣的表現,但是我想減少這種差異。

感謝您的回覆。 此致敬禮。

回答

0

我認爲這裏的問題是開銷。當你將一個循環聲明爲並行時,它會分配所有的線程來一次執行它們的for循環的一部分。當你開始一項任務時,每次啓動任務時都必須完成整個設置過程。爲什麼不只是做以下事情。

#pragma omp parallel num_threads(threadsNumber) 
{ 
    #pragma omp master 
    { 
     for(int ts=0; ts<1000; ++ts) 
     { 
      #pragma omp for 
      for(int th=0; th<threadsNumber; ++th) 
      { 
        for(int i=th*blockSize; i<th*blockSize+blockSize; ++i) 
        { 
         array_32[i] = array_12[i] * array_22[i]; 
        }     
      } 


     } 
    } 
} 
0

我想說的是,你在這裏進行試驗的問題是關係到數據的親和力:當您使用#pragma omp for跨線程的迭代的分配始終是的ts所有的值相同,而任務中你沒有辦法指定任務與線程的綁定。

曾經說過,我執行你的程序在我的機器上用1M元素的三個數組和兩個版本之間的結果比較接近:

  • t1_for:2.041443s
  • t1_tasking:2.159012s

(我用過GCC 5.3.0 20151204