Openmp并行do循环正确运行〜50%的时间

时间:2019-04-15 03:00:53

标签: fortran openmp

我目前正在为我编写的用于研究的代码之一为do循环添加openmp并行化。我对使用openmp相当陌生,因此如果您对可能出现的问题有任何建议,将不胜感激。

基本上,我在以下代码中添加了并行do循环(在并行化之前有效)。 r(:,:,,:,:)是按时间,分子,原子和(xyz)索引的一吨分子坐标的向量。该向量大约有100 gb的数据(我正在使用具有大量RAM的HPC)。我正在尝试并行化外循环并在处理器之间对其进行细分,以便可以减少此计算所需的时间。我认为这将是一个很好的选择,因为msd和cm_msd是唯一需要由多个处理器编辑并存储以供以后使用的东西,因为每次迭代都获得了这些数组的自己的元素,所以它们将不再需要比赛条件。

问题:如果我多次运行此代码5次,结果将有所不同,有时msd的计算正确(或看起来是正确的),有时在我将其平均后,它会输出全零。没有并行化就没有问题。

我一直在尝试更改代码中的共享变量与私有变量,我想我已经考虑了所有问题。 msd数组和msd_cm数组的i索引在线程之间永远不应相等,因此我认为它们不会成为问题。

! Loop over time origins
    counti = 0
    ind = 0
    !$OMP PARALLEL DO schedule(static) PRIVATE(i,j,k,it,r_old,r_cm_old,shift,shift_cm,dsq,ind) &
    !$OMP& SHARED(msd,msd_cm)
    do i=1, nconfigs-nt, or_int
        if(MOD(counti*or_int,500) == 0) then
            write(*,*) 'Reached the ', counti*or_int,'th time origin'
        end if
        ! Set the Old Coordinates
        counti = counti + 1
        ind = (i-1)/or_int + 1
        r_old(:,:,:) = r(i,:,:,:)
        r_cm_old(:,:) = r_cm(i,:,:)
        shift = 0.0
        shift_cm = 0.0

        ! Loop over the timesteps in each trajectory
        do it=i+2, nt+i
            ! Loop over molecules
            do j = 1, nmols
                do k=1, atms_per_mol
                    ! Calculate the shift if it occurs.
                    shift(j,k,:) = shift(j,k,:) - L(:)*anint((r(it,j,k,:) - &
                        r_old(j,k,:) )/L(:))
                    ! Calculate the square displacements
                    dsq = ( r(it,j,k,1) + shift(j,k,1) - r(i,j,k,1) ) ** 2. &
                         +( r(it,j,k,2) + shift(j,k,2) - r(i,j,k,2) ) ** 2. &
                         +( r(it,j,k,3) + shift(j,k,3) - r(i,j,k,3) ) ** 2.
                    msd(ind, it-1-i, k) = msd(ind, it-1-i, k) + dsq
                    ! Calculate the contribution to the c1,c2
                enddo ! End Atoms Loop (k)
                ! Calculate the shift if it occurs.
                shift_cm(j,:) = shift_cm(j,:) - L(:)*anint((r_cm(it,j,:) - &
                                r_cm_old(j,:) )/L(:))
                ! Calculate the square displacements
                dsq = ( r_cm(it,j,1) + shift_cm(j,1) - r_cm(i,j,1) ) ** 2. &
                    +( r_cm(it,j,2) + shift_cm(j,2) - r_cm(i,j,2) ) ** 2. &
                    +( r_cm(it,j,3) + shift_cm(j,3) - r_cm(i,j,3) ) ** 2.
                msd_cm(ind,it-1-i) = msd_cm(ind, it-1-i) + dsq
            enddo ! End Molecules Loop (j)
            r_old(:,:,:) = r(it,:,:,:)
            r_cm_old(:,:) = r_cm(it,:,:)
       enddo ! End t's loop (it)
    enddo
    !$OMP END PARALLEL DO

运行此代码时,稍后我打印出平均的msd结果时,它们要么正确输出,要么输出为零,并且始终为一个或另一个。您是否看到一个问题可以解释为什么它仅在部分时间内起作用?我是openmp的新手,所以完全有可能对我的尝试非常愚蠢。

谢谢!

0 个答案:

没有答案