2014-02-11 27 views
0

截至目前,我的每個函數都有兩個線程。 Ax和Sword是Matrix對象。在C++中被問及多線程乘法運算11

thread thrd1(Add, std::ref(Axe), std::ref(Sword), std::ref(Axe)); 
thread thrd2(Multiply, std::ref(Axe), std::ref(Sword), std::ref(Axe)); 

我是線程新手,不太瞭解它。我必須將線程添加到我的乘法函數中嗎?現在它僅僅是

//Multiply the matrices 
void Multiply(Matrix &a, Matrix &b, Matrix &c){ 
    for (auto i=0; i<c.dx; ++i) { 
     for (auto j=0; j<c.dy; ++j) { 
      for (auto k=0; k<a.dy; ++k) { 
       c.p[i][j] += a.p[i][k] * b.p[k][j]; 
      } 
     } 
    } 
} 

,但我覺得,如果我需要別的東西補充,由於他們在時間上沒有減少,同時通過設置的OpenMP線程數。誰能幫我嗎?

回答

0

首先:OpenMP和std :: thread/future/etc。是不同的東西。如果你想使用OpenMP,那裏有幾個相當不錯的教程可供查找,但是它可以歸結爲你的第一個循環前面的一個預處理器命令,我猜。

現在來看看C++ 11的一部分:我想從你的問題(這方面還不太清楚),你傳遞函數在線程中運行。這不會減少任何計算時間,因爲您的代碼仍然在一個線程中運行。現在,你想要做的,每次你寫多線程代碼是什麼你猜怎麼着「多」中的「多線程」是指...

  1. 想想你如何可以將工作分成(理想大小相同)不相交問題。這裏不相交表示無論你計算什麼都不依賴於其他計算的結果。在你的情況下注意矩陣或列/行的單個結果元素的計算可以獨立於其他計算。

  2. 無論這種「子計算」寫入什麼,都必須寫入其他線程不同時寫入的位置。如果這是必要的,有辦法解決這個問題(例如互斥體),但是通常可以定義問題在內存中是固有獨立的(就像你的情況,每個工作線程只能寫入一列)。

  3. 編寫一個做這樣一個子任務的函數(例如限制你的函數只計算你傳遞的一列作爲參數)並且爲所有的子任務創建std :: thread或者std :: future對象(後者使用std :: async),將它們的子任務函數與它們相應的參數一起傳遞給它們,並等待它們完成(使用thread :: join)。

請注意,編寫多線程代碼以減少任何非純功能語言中的小問題可能會很快變得非常複雜。您應該花些時間閱讀一些教程或書籍。作爲一個開始,也許看看此YouTube列表:https://www.youtube.com/playlist?list=PL5jc9xFGsL8E12so1wlMS0r0hTQoJL74M

哦,差點忘了它: 在你的功能,你不需要寫要麼ab,因此應該通過const引用傳遞它們。在線程建設網站上,您必須使用std::cref。編寫多線程代碼時,Const的正確性非常重要。

+0

那麼我將如何去「設置」一些線程的使用,說我需要只使用4線程,谷歌搜索顯示openMP作爲解決方案 –

+0

你「通過實例化許多'std :: thread'對象來設置「多個線程」。爲了獲得大量的線程,你可以使用'std :: thread :: hardware_concurrency'。明確地陳述你的要求是非常好的 - 這是爲了學習c + 11線程設施而進行某種練習,還是你真的需要這個功能?我個人對穩定和快速數字計算的看法是:不要自己寫。 –

1

所有你需要做的就是這個

void Multiply(Matrix &a, Matrix &b, Matrix &c) { 
    #pragma omp parallel for 
    for (int i=0; i<c.dx; ++i) { 
     for (int j=0; j<c.dy; ++j) { 
      for (int k=0; k<a.dy; ++k) { 
       c.p[i][j] += a.p[i][k] * b.p[k][j]; 
      } 
     } 
    } 
} 

你可能不希望擔心線程數。讓OpenMP選擇默認值。這將被設置爲邏輯核心的數量。但是,如果您使用超線程技術,則可能有助於將線程數設置爲物理內核數而不是邏輯內核數。

你也可能想嘗試融合循環。像這樣

#pragma omp parallel for 
for(int n=0; n<c.dx*c.dy; n++) { 
    int i=n/c.dy; 
    int j=n%c.dy; 

然而,當你閱讀b.p[k][j]很可能將有很多高速緩存未命中。一個更好的解決辦法是把b的轉置和轉置作爲b.p [j] [k]進行存取。

更好的解決方案是使用瓦片/塊矩陣乘法。請參閱以下鏈接如何做reading/writing a matrix with a stride much larger than its width causes a big loss in performance