2015-10-10 81 views
0

我試圖簡單地用openmp並行MD代碼。但是,即使我用openmp使用一個線程。結果不正確。如果我推薦了代碼的omp部分,結果是正確的。我認爲這個問題是omp中共享和私有變量的錯誤使用。任何人都可以幫我解決這個問題嗎?非常感謝你!代碼如下openmp共享和私有成員

int i, j; 
// parallelization using openmp 
#pragma omp parallel shared(fx2,fy2,fz2,rx,ry,rz,N_molecular,L) private(i, j, xmin, ymin, zmin,rmin2, f) 
{ 
    #pragma omp for// reduction(+:fx2,fy2,fz2) 
    /*calculate all pair forces acting on each particles again*/ 
    for(i = 0; i < N_molecular-1; i++){ 
     for(j = i+1; j < N_molecular; j++){ 
      xmin = rx[i] - rx[j] - L*round ((rx[i] - rx[j])/L); 
      ymin = ry[i] - ry[j] - L*round ((ry[i] - ry[j])/L); 
      zmin = rz[i] - rz[j] - L*round ((rz[i] - rz[j])/L); 
      rmin2 = xmin*xmin + ymin*ymin + zmin*zmin; 
      if(rmin2 < rcut*rcut) 
      { 
       f = 48./pow(rmin2,7) - 24./pow(rmin2,4); 
       //#pragma omp atomic update 
       fx2[i] += f*xmin; 
       //#pragma omp atomic update 
       fy2[i] += f*ymin; 
       //#pragma omp atomic update 
       fz2[i] += f*zmin; 
       //#pragma omp atomic update 
       fx2[j] = fx2[j] - f*xmin; 
       //#pragma omp atomic update 
       fy2[j] = fy2[j] - f*ymin; 
       //#pragma omp atomic update 
       fz2[j] = fz2[j] - f*zmin; 
      } 
     } 
    } 
} 

回答

0

在parallelising這段代碼棘手的部分是確保爲部隊陣列更新不會產生競爭條件。在這裏,當使用i索引完成時,不會發生問題,因爲不同的線程將處理不同的i索引。但是,這對於j索引並不正確,這足以阻止您使用此方法。

一個解決方案是將你的力量存儲在本地每個線程數組中,並在並行區域退出時在全局數組中累積最終單個結果。其他可能性存在,我在this answer to a question very similar to yours中描述(我希望)的細節。