2016-10-21 26 views
2

我檢查別人的OpenMP代碼摺疊兩個用於-循環了三次,看到這三個嵌套for循環,只有(第一個?)有兩個人被倒塌:OpenMP中

#pragma omp for collapse(2) 
    for(int i=0;i<nxn;i++) 
    for(int j=0;j<nyn;j++) 
    for(int k=0;k<nzn;k++) 
    { 
    rhons[is][i][j][k] += invVOL*moments[i][j][k][0]; 
    Jxs [is][i][j][k] += invVOL*moments[i][j][k][1]; 
    Jys [is][i][j][k] += invVOL*moments[i][j][k][2]; 
    Jzs [is][i][j][k] += invVOL*moments[i][j][k][3]; 
    pXXsn[is][i][j][k] += invVOL*moments[i][j][k][4]; 
    pXYsn[is][i][j][k] += invVOL*moments[i][j][k][5]; 
    pXZsn[is][i][j][k] += invVOL*moments[i][j][k][6]; 
    pYYsn[is][i][j][k] += invVOL*moments[i][j][k][7]; 
    pYZsn[is][i][j][k] += invVOL*moments[i][j][k][8]; 
    pZZsn[is][i][j][k] += invVOL*moments[i][j][k][9]; 
    } 

我的問題是,是否有可能崩潰所有三個循環?我的意思是我試圖理解開發者的邏輯(他應該是非常有經驗的) - 爲什麼他沒有這樣做?

+1

摺疊外層循環的動機是將工作更均勻地分佈在各個線程之間。將內部循環包含在崩潰中會干擾向量化,可能會阻止它,除非您設置simd並使用合適的編譯器。 – tim18

+1

接受的答案是錯誤的! –

+2

好的,如果這些回覆仍然令人困惑,collapse(2)會合並2個外部循環,並使內部循環受制於編譯器設置,例如自動向量化。這可能是一個不錯的選擇。 – tim18

回答

3

你可以這樣做,但它會帶來什麼好處?我們假設nxn * nyn明顯更大OMP_NUM_THREADS。所以已經有循環迭代被高效並行化。

另一方面,內循環具有很高的數據局部性。雖然OpenMP可能會保持這一點,但是可能會有一個特定的優化,即數組的最後一個維度是緩存行的倍數 - 因此將它們分割成多個線程是不明智的。正如tim18所提到的,當摺疊所有循環時,可能會干擾內部循環的矢量化可能會成爲另一個問題。

所以基本上,它沒有任何好處,但它可能會對愚蠢的OpenMP實現的性能造成影響。