2013-02-07 56 views
2

我想測試一個小塊代碼的速度,如下所示:巨大的減緩使用OpenMP

for(i=0;i<imgDim;i++) 
     { 
      X[0][i] = Z[i] - U1[i] * rhoinv; 
      X[1][i] = Z[i] - U2[i] * rhoinv; 
      X[2][i] = Z[i] - U3[i] * rhoinv; 
     } 

迭代大約是200和imgDim是1000000的這段代碼的總時間大約2秒。整個代碼大約需要15秒。 但經過我使用的openmp平行這段代碼等:

omp_set_num_threads(max_threads); 
    #pragma omp parallel shared(X,Z,U1,U2,U3,imgDim,rhoinv) private(i) 
    { 
     #pragma omp for schedule(dynamic) 
     for(i=0;i<imgDim;i++) 
     { 
      X[0][i] = Z[i] - U1[i] * rhoinv; 
      X[1][i] = Z[i] - U2[i] * rhoinv; 
      X[2][i] = Z[i] - U3[i] * rhoinv; 
     } 
    } 

max_threads的是8.只有這小片的代碼需要約11秒,約27秒整個代碼使用。最奇怪的是,如果我將max_threads更改爲1,則時間會減少到6秒。但仍比順序代碼長很多。

這花了我很多時間,我找不到問題。深表謝意,如果有人能幫助我。

+0

你可能是內存bound-如果你已經飽和了你的內存總線,有更多的線程堆棧請求(以及有自己的開銷,包括上下文切換的內存訪問)將無濟於事。 – zebediah49

+0

我猜想問題是,每個線程工作,只有幾個倍增和增加,只是完全被代碼淹沒,以創建/運行/銷燬並行線程。嘗試(對於i = 0;我}}以確保每個線程的工作量更大 –

回答

3

schedule(dynamic)引入了巨大的運行時間開銷。它只能用於循環,每次迭代可能需要不同的時間,並且改進的負載平衡將證明開銷。對於像您這樣的常規循環而言,動態調度是一種矯枉過正,因爲它會引入不必要的開銷,從而減慢計算速度。

更改計劃類型static

#pragma omp parallel for schedule(static) 
for(i=0;i<imgDim;i++) 
{ 
    X[0][i] = Z[i] - U1[i] * rhoinv; 
    X[1][i] = Z[i] - U2[i] * rhoinv; 
    X[2][i] = Z[i] - U3[i] * rhoinv; 
} 

(注:在外部範圍聲明的變量默認共享和並行循環控制變量是隱含私人)

+0

非常感謝。 – mining