2016-05-17 43 views
0

我想學習OpenMP並行化我的代碼的一部分,我試圖找出爲什麼它不是更快時,使用2個線程而不是1.這裏是的代碼的最小工作示例:沒有得到預期的加速使用OpenMP的非平凡的計算

#include <iostream> 
#include <omp.h> 

using namespace std; 

class My_class 
{ 
    public : 

     // Constructor 
     My_class(int nuIterations) 
      : prVar_(0), 
       nuIters_(nuIterations) 
     {} // Empty 

     // Do something expensive involving the class' private vars 
     void do_calculations() 
     { 
      for (int i=0;i<nuIters_;++i){ 
       prVar_=prVar_+i+2*i+3*i+4*i-5*i-4*i; 
      } 
     } 

     // Retrieve result 
     double getResult() 
     { 
      return prVar_; 
     } 

    private: 

     double prVar_; 
     int nuIters_; 

}; 

int main() 
{ 
    // Initialize one object for every thread 
    My_class *test_object1, *test_object2; 
    test_object1 = new My_class(1000000000); 
    test_object2 = new My_class(500000000); 

    // Set number of threads (use one line at a time) 
    omp_set_num_threads(1); // One thread executes in 11.5 real seconds 
    //omp_set_num_threads(2); // Two threads execute in 13.2 real seconds 
    double start = omp_get_wtime(); // Start timer 
#pragma omp parallel sections // Do calculations in parallel 
    { 
#pragma omp section 
     { 
      test_object1->do_calculations(); 
     } 
#pragma omp section 
     { 
      test_object2->do_calculations(); 
     } 
    }// End of parallel sections 
    // Print results 
    double end = omp_get_wtime(); 
    cout<<"Res 1 : "<<test_object1->getResult()<<endl; 
    cout<<"Res 2 : "<<test_object2->getResult()<<endl; 
    cout<<"Time : "<<end-start<<endl; 

    return 0; 
} 

編譯和運行這個使用g++ myomp.cpp -O0 -std=c++11 -fopenmp給出了1個2個線程以下執行時間:

  1. 1螺紋:11.5秒
  2. 2線程:13.2秒

有什麼方法可以加速2線程? 我在4核英特爾i7-4600U和Ubuntu上運行此操作系統。

編輯:改變了大多數帖子,使其遵循指導。

+2

您必須以[mcve]加上您的硬件規格的形式給我們提供更多信息,否則答案只是猜測。猜測包括:寫入共享緩存行,進行內存綁定,隱式同步,使用您不知道的共享資源或其組合。 – Zulan

+0

感謝您的評論,我會嘗試制定一個合適的示例並編輯帖子! – nikaza

+0

完成,希望它現在有意義! – nikaza

回答

2

有兩隻方面的影響在這裏:

  1. 緩存行爭:您必須在動態內存分配了兩個非常小的物體。如果它們結束於同一個緩存行(通常是64字節),那麼想要更新的線程將同時競爭1級緩存,因爲它們需要獨佔(寫入)訪問權限。您應該已經隨機觀察到了這種情況:有時,根據內存位置,它顯着更快/更慢。嘗試打印指針地址並將它們除以64.要解決此問題,您需要pad/align the memory

  2. 您有巨大的負載不平衡。一項任務僅僅是計算兩倍的工作量,因此即使在理想條件下,也只能達到1.5的加速。

+0

我向私有變量添加了一個1000元素的雙精度數組(試圖將兩個對象分隔得比一個高速緩存線更遠),它根本沒有任何區別... –

+0

「沒有區別」是什麼意思?如果您已經獲得了1.5倍加速,那麼您可能不會受到1)的影響。 – Zulan

+0

同意。我試圖說,似乎沒有任何緩存線爭用,但我說得很糟糕。我也試着讓這兩種工作負載大小相同,加速比例確實是2倍。所以,至少在我的機器上,它似乎幾乎完全是你的第二個效果。有我的投票:-) –