2012-03-31 125 views
6

我正在嘗試使用我正在使用的程序並得到以下問題。 如果多個線程需要在同一個矢量上讀取/寫入,但是矢量的不同元素會損失性能嗎?我感覺這就是我的程序在對其進行平滑處理時幾乎沒有得到更快的原因。看看下面的代碼:OpenMP中的共享向量

#include <vector> 

int main(){ 

    vector<double> numbers; 
    vector<double> results(10); 
    double x; 

    //write 10 values in vector numbers 
    for (int i =0; i<10; i++){ 
     numbers.push_back(cos(i)); 
    } 

#pragma omp parallel for \ 
    private(x) \ 
    shared(numbers, results) 
     for(int j = 0; j < 10; j++){ 

      x = 2 * numbers[j] + 5; 
#pragma omp critical // do I need this ? 
      { 
       results[j] = x;  
      } 
     } 

    return 0; 

} 

顯然,實際的程序確實更加昂貴的操作,但這個例子應 只能說明我的問題。那麼for循環可以快速完成並行,或者不同的線程必須等待對方,因爲一次只有一個線程可以訪問向量編號,儘管它們都讀取了向量的不同元素?

與寫操作相同的問題:我需要的關鍵編譯或因爲每個線程寫入矢量結果的不同元素是沒有問題? 我很高興能得到每一個幫助,也很高興知道是否有更好的方法來做到這一點(也許根本不使用向量,但簡單的數組和指針等?) 我也讀向量aren 「T在某些情況下是線程安全的,建議使用指針:OpenMP and STL vector

非常感謝您的幫助!

回答

7

我想,大多數在多線程向量的問題是,如果它有調整,然後將其複製向量的全部內容複製到內存中的新位置(一個更大的分配塊),如果你是哪個並行訪問這個,然後你試着讀取一個已經被刪除的對象。

如果不調整您的磁盤陣列,然後我還從未有過併發讀取任何問題(只要顯然是我不寫相同的元素兩次)寫入矢量

至於缺的性能提升,openmp臨界區會將你的程序降低到與使用1個線程相同的程度(取決於在該臨界區以外實際完成多少操作)

您可以刪除臨界區語句以上記)。

+0

他不調整向量的。 – eudoxos 2012-03-31 09:22:39

+0

@eudoxos我意識到,從代碼片段,我只是想確保有人提到,特別是因爲他提出了一個事實,即STL矢量某些條件下不會 – SirGuy 2012-03-31 12:43:23

+0

+1線程安全:它不會真的拿出在這裏,但你必須記住特定向量的操作,如追加,調整大小等不是線程安全的,並可能會中斷。但只要每個元素只由一個線程寫入,只需操作矢量的元素就沒有問題。 – 2012-03-31 15:35:14

5

你沒有加速正是由於關鍵性sectino,這是多餘的,因爲相同的元素絕不會在同一時間進行修改。刪除關鍵部分,它會工作得很好。

您可以通過調度策略發揮好,因爲如果內存訪問是不是線性的(這是你給的例子),線程可能緩存打(在同一高速緩存行寫元素)。 OTOH如果元素的數量按照你的情況給出,並且循環中沒有分支(因此它們將以大約相同的速度執行),static,這是默認的IIRC,無論如何應該工作得最好。

(順便說一句,你可以聲明x內循環,避免private(x)shared指令暗示IIRC(我從來沒有使用過)。)

+0

+1;如果你沒有調整大小或追加到矢量或者你有什麼矢量,它只是一個1d數組,並且OpenMP非常擅長操作數組。至於靜態,私有等,我認爲「最佳實踐」是使用默認(none),並將所有內容明確地私有或共享,只是爲了明確,並且@eudoxos指出,在並行範圍中定義了變量部分使它們隱含私有,然後跟隨代碼更容易一些。 – 2012-03-31 15:36:32

+0

嗨,感謝您的幫助。在循環中聲明x是否真的更快(每個線程都會聲明它,然後),而不是像上面那樣在循環之前,還是它具有相同的性能,但更好看?這是什麼意思,內存訪問不是線性的,爲什麼這樣呢? – user1304680 2012-04-01 19:08:24

+0

@ user1304680:聲明是針對編譯器的,它只是說你想擁有一些尺寸的內存並在後續代碼中以某種方式調用它。我懷疑任何像樣的,適度優化的編譯器都會有所作爲。非線性訪問:我的意思是隨機訪問相鄰內存區域中線程的元素。隨後,RAM向CPU提供大塊內存,該內存大於矢量項。如果2個內核訪問附近的RAM塊,它可能在同一個緩存行中,然後它們在hw級別同步,但會使其變慢。除非需要,否則不要擔心。 – eudoxos 2012-04-02 11:54:17