2013-10-15 83 views
1

我正在嘗試將openmp應用於下面的代碼片段中,如下所示。然而,並行代碼的運行速度比沒有openmp派生函數的代碼慢。我在64位Linux平臺上運行,並使用gfortran進行編譯。 您對如何正確使用它的意見和建議表示感謝!openmp fortran代碼比串行代碼運行速度慢

 call omp_set_num_threads(4) 

    do i = 2, natoms - 1 

      rti(1:3) = R_for(i,1:3) 
      fti(1:3) = ftmp(i,1:3) 

    !$OMP PARALLEL DO DEFAULT(SHARED)& 
    !$OMP& private(rtij,rsqij,rsqijinv,sr2,sr6,sr12,vij,wij,fij,ftij,ncut)& 
    !$OMP& REDUCTION(+:vtmp,wtmp,ftmp,fti) & 
    !$OMP& firstprivate(i,rti,R_for) 

    do j = i + 1, natoms 
     rtij = rti - R_for(j,1:3) 
     rtij = rtij - boxl*idnint(rtij*boxlinv) 
     rsqij = sum(rtij**2) 

       if(rsqij.lt.rcutsq) then 
        rsqijinv = 1d0/rsqij 
        sr2 = sigsq*rsqijinv 
        sr6 = sr2*sr2*sr2 
        sr12 = sr6*sr6 
        vij = sr12 - sr6 
        vtmp = vtmp + vij 
        wij = vij + sr12 
        wtmp = wtmp + wij 
        fij = wij*rsqijinv 

        ftij = fij*rtij 
        fti = fti + ftij 
        ftmp(j,1:3) = ftmp(j,1:3) - ftij(1:3) 
        ncut = ncut + 1 
       endif 
enddo 
    !$OMP END PARALLEL DO 

     ftmp(i,1:3) = fti(1:3) 
enddo 
+3

爲並行化設置「線程」需要花費成本,所以如果它沒有做太多或者它們阻止訪問公共資源,那麼它不會更快,實際上它可能會更慢。整理你的代碼,把它做成平行的代碼,以及一些模糊的線索,說明它的做法是否合適。 –

+0

我已刪除評論並清理代碼。我主要想知道兩件事情:1.在我沒有發現的並行循環中是否有看不見的依賴。 2.任何其他方式來改善它 – user1509376

回答

1

如由Tony霍普金森提到的,線程創建引入了一些額外開銷,因而你應該從外循環的移動並行區域,並把共享變量的分配到一個或WORKSHARE單個構建體。

然後,代替reduction子句,可以使用線程數長度的數組來存儲線程局部部分總和,並且僅在循環完成後執行減少vtmp和wtmp例如看起來沒有被使用,並且即使在外環之後也可以減小。由於if條件,它看起來像循環可能在迭代到迭代之間嚴重不平衡,並且使用某些動態調度可能會有所幫助。

相關問題