2016-01-23 88 views
0

我想並行化一塊C++代碼與OpenMp,但我面臨一些問題。事實上,我的並行代碼並不比串行代碼快。 我想我已經理解了這個原因,但我無法解決它。在OpenMP共享陣列

我的代碼的結構是這樣的:

int vec1 [M]; 
int vec2 [N]; 

...initialization of vec1 and vec2... 

for (int it=0; it < tot_iterations; it++) { 

if ((it+1)%2 != 0) { 

    #pragma omp parallel for 

    for (int j=0 ; j < N ; j++) { 

    ....code involving a call to a function to which I'm passing as a parameter vec1..... 

if (something) { vec2[j]=vec2[j]-1;} 

} 
} 
else { 
    # pragma omp parallel for 

    for (int i=0 ; i < M ; i++) { 

    ....code involving a call to a function to which I'm passing as a parameter vec2..... 

if (something) { vec1[i]=vec1[i]-1;} 

} 
} 

} 

我想,也許我的並行代碼變慢了,因爲多個線程想訪問同一共享陣列和一個必須等​​待,直到另一個已經完成,但我不確定事情真的如何。但我不能使vec1和vec2保密,因爲在其他迭代中不會看到更新... 我該如何改進它?

回答

0

當您在使用多個線程訪問同一個數組時遇到問題時,這稱爲「假分享」。除非你的數組很小,否則它不應該成爲瓶頸,因爲pragma omp parallel for在默認實現中使用靜態調度(至少使用gcc),因此每個線程都應該訪問大部分數組,除非你的「...涉及調用我作爲參數vec2傳入的函數.....「真正訪問數組中的很多元素。

案例1:你不訪問大多數元素的數組中的代碼

  • ,這部分是M大到足以使並行有用嗎?
  • 你可以在外環上移動平行度嗎? (有一個循環只有VEC 1,另一個用於VEC 2只)
  • 嘗試移動並行區域代碼:

    int vec1 [M]; 
    int vec2 [N]; 
    
    ...initialization of vec1 and vec2... 
    #pragma omp parallel 
    for (int it=0; it < tot_iterations; it++) { 
    
        if ((it+1)%2 != 0) { 
         #pragma omp for 
         for (int j=0 ; j < N ; j++) { 
         ....code involving a call to a function to which I'm passing as a parameter vec1..... 
    
          if (something) { vec2[j]=vec2[j]-1;} 
    
         } 
        } 
    else { 
        # pragma omp for 
        for (int i=0 ; i < M ; i++) { 
        ....code involving a call to a function to which I'm passing as a parameter vec2..... 
    
         if (something) { vec1[i]=vec1[i]-1;} 
    
        } 
    } 
    

這應該不會有太大變化,但一些實施有一個昂貴的並行區域創建。

案例2:你訪問的每個元素與每個線程

我會說你不能這樣做,如果你執行更新,否則,你可能有併發性問題,因爲你必須在循環順序的依存關係。