有什么方法可以避免在Fortran 90中嵌套嵌套循环?

时间:2019-03-24 00:09:10

标签: fortran fortran90

我正在读取沿时间轨迹的分子速度。我正在尝试计算v_i(t)* v_j(t + n∆t),其中i和j不一定是同一原子。

我使用嵌套的do循环进行计算,根据定义,该计算适用于不同的时间步长,不同的分子和不同的原子。我有多个嵌套的do循环,这会降低代码速度并导致内存问题。如果可能,我想避免这些问题。如何使用Fortran 90改进代码?

   PROGRAM BUILD

   IMPLICIT NONE
   INTEGER :: I,K,L,L1,L2,M1,M2,T,T1,T2,NCON,NMOL,NSIT,SPLIT,LOOP
   REAL(8) :: X,Y,Z,V1,V2,V3,R,TRASH
   REAL(8),ALLOCATABLE :: VX(:,:,:),VY(:,:,:),VZ(:,:,:)
   REAL(8),ALLOCATABLE :: NORM(:,:,:,:,:),V(:,:,:,:,:)

   ! Input

   NCON = 100001 ! Number of configurations
   NMOL = 524 ! Number of molecules
   NSIT = 6 ! Number of sites on each molecule

   SPLIT = 50 ! Number of subgroups of configurations
   LOOP = (NCON-1)/SPLIT ! Number of configurations in each subgroup

   !       *       *       *       *       *       *       *       *       *

   ! Allocate memory

   ALLOCATE ( VX(0:LOOP,NMOL,NSIT) )
   ALLOCATE ( VY(0:LOOP,NMOL,NSIT) )
   ALLOCATE ( VZ(0:LOOP,NMOL,NSIT) )
   ALLOCATE ( V(0:LOOP,NMOL,NMOL,NSIT,NSIT) )
   ALLOCATE ( NORM(0:LOOP,NMOL,NMOL,NSIT,NSIT) )
   ALLOCATE ( VIVJ(0:LOOP,NSIT,NSIT) )
   ALLOCATE ( N(0:LOOP,NSIT,NSIT) )

   ! Initialize

   VX = 0.0D0
   VY = 0.0D0
   VZ = 0.0D0
   V = 0.0D0
   NORM = 0.0D0
   VIVJ = 0.0D0
   N = 0.0D0

   ! Read trajectories

   OPEN(UNIT=15,FILE='HISTORY',STATUS='UNKNOWN',ACTION='READ')
   DO I = 1,SPLIT
      WRITE(*,*) I,SPLIT
      DO T = 0,LOOP-1
         DO L = 1,NMOL
            DO K = 1,NSIT
               READ(15,*) V1,V2,V3

               VX(T,L,K) = V1
               VY(T,L,K) = V2 
               VZ(T,L,K) = V3

            END DO

         END DO

      END DO

      ! Calculate functions

      DO T1 = 1,LOOP

         DO T2 = T1,LOOP

            DO L1 = 1,NMOL

               DO M1 = 1,NSIT

                  DO L2 = 1,NMOL

                     DO M2 = 1,NSIT

                        ! Includes all atoms, both intermolecular and intramolecular

                        ! Keep all of the molecules
                        V(T2-T1,L1,L2,M1,M2) = V(T2-T1,L1,L2,M1,M2) + & 
                                         VX(T1,L1,M1)*VX(T2,L2,M2) + & 
                                         VY(T1,L1,M1)*VY(T2,L2,M2) + & 
                                         VZ(T1,L1,M1)*VZ(T2,L2,M2)

                        ! Accounting
                        NORM(T2-T1,L1,L2,M1,M2) = NORM(T2-T1,L1,L2,M1,M2) + 1.0D0

                     END DO

                  END DO

               END DO

            END DO

         END DO

      END DO

   CLOSE(15)

   DEALLOCATE(VX)
   DEALLOCATE(VY)
   DEALLOCATE(VZ)
   DEALLOCATE(V)
   DEALLOCATE(NORM)

   END PROGRAM

1 个答案:

答案 0 :(得分:2)

Fortran以不同于C和其他大多数语言的顺序存储数组。

do T = ...
    do L = ...
        do K = ...
            array(T, L, K) = ...
        end do
    end do
end do

总是会比

慢得多
do K = ...
    do L = ...
        do T = ...
            array(T, L, K) = ...
        end do
    end do
end do

所有其他条件都一样。