1

I am trying to apply openmp to parallize the following snippet as shown below. However, the paralleled code turns out to be running slower than serial one without the openmp derivatives. I am running on 64 linux platform and compile with gfortran. You comments and suggestions about how to do it properly are appreciated!

        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
4

1 回答 1

1

正如 Tony Hopkinson 所提到的,线程创建引入了一些开销,因此您应该将并行区域移出外部循环并将共享变量的分配放入工作共享或单个构造中。

然后,代替归约子句,您可以使用具有线程数长度的数组来存储线程局部部分和,并仅在循环完成后进行归约 vtmp 和 wtmp 例如似乎无处可使用,甚至可以减少在外循环之后。由于 if 条件,看起来您的循环可能在迭代之间严重不平衡,使用一些动态调度可能是有益的。

于 2013-10-16T00:03:22.353 回答