Optimization 优化从循环调用子例程的次数
关于优化程序的一个小问题。问题陈述如下 问题陈述: 主代码有一个for/DO循环,其中有一个子例程。子例程是否需要执行取决于我从用户收到的标志 显而易见的解决方案: 最简单的方法是使用IF循环调用子例程。但是,如果每次执行循环时都必须检查标志,那么这将非常耗时。我在做分子动力学,循环的次数是10^5 Qn:有没有更好的方法来实现这一点,就像我对程序说的,是否必须根据标志一次性调用子例程?我正在用Fortran 90编写代码。因此,如果可以这样说,那将是有益的Optimization 优化从循环调用子例程的次数,optimization,fortran,fortran90,Optimization,Fortran,Fortran90,关于优化程序的一个小问题。问题陈述如下 问题陈述: 主代码有一个for/DO循环,其中有一个子例程。子例程是否需要执行取决于我从用户收到的标志 显而易见的解决方案: 最简单的方法是使用IF循环调用子例程。但是,如果每次执行循环时都必须检查标志,那么这将非常耗时。我在做分子动力学,循环的次数是10^5 Qn:有没有更好的方法来实现这一点,就像我对程序说的,是否必须根据标志一次性调用子例程?我正在用Fortran 90编写代码。因此,如果可以这样说,那将是有益的 PROGRAM MAIN I
PROGRAM MAIN
IMPLICIT NONE
"ALL ARRAY INITIALIZATIONS
CALL DENSITY() ! I do a field based approach. So this is for grid formulation
DO i = 1, neq ! neq = number of eqbm cycles
CALL MC_CYC() ! Monte carlo steps
CALL DENSITY() ! Recalculate density
END DO
DO i = 1,nprod ! production cycle
DO j = 1, niter ! for averages of ensembles
CALL MC_CYC()
CALL DENSITY()
END DO
!do average here
IF(<flag is present>) ! This is where I needed to check flag. Because otherwise the flag will be checked everytime.
CALL RDF()
END IF
END DO
END PROGRAM MAIN
主程序
隐式无
“所有数组初始化
调用DENSITY()!我使用基于字段的方法。所以这是网格公式
i=1,neq!neq=eqbm循环数
调用MC_CYC()!蒙特卡罗步骤
调用密度()!重新计算密度
结束
i=1,nprod!生产周期
对于合奏的平均值,j=1,niter
调用MC_CYC()
呼叫密度()
结束
!你在这里平均吗
IF()!这是我需要检查标志的地方。否则每次都会检查标志。
调用RDF()
如果结束
结束
主程序结束
我不确定IF
语句是否真的会降低程序的速度,即使调用了(超过)100000次。通过重新构造代码,您可能只会节省一两秒钟的时间(尽管要测试!)
无论如何,如果在程序开始时收到该标志,那么您就可以将代码编写为
IF(<flag is present>) THEN
DO
...
CALL <subroutine name>
...
ENDDO
ELSE
DO
...
ENDDO
ENDIF
哇,Fortran 90…你在哪里使用它?@AdamStelmaszczyk“在哪里?”“在这个意义上?我用它来进行分子动力学编码。如果你在做MD,我想在你的do循环中会有很多其他的操作。那么,
如果
就根本不重要了。不要试图优化你的单个ıf
语句,试着优化代码的那一部分,这会占用你的时间。但是,首先,分析你的代码,以便知道它在哪里花费了大部分的执行时间。有一件小事我之前没有告诉你。无论标志是否存在,都需要执行DO循环,因为存在其他子例程(无论标志如何,这些子例程都是必需的)。有一些用于后处理的子程序,只有在标志为true时才需要调用这些子程序。如果我这样做,整个循环(它本身很大,需要写两次)@Vaidyanathan:我在我的答案中添加了第二个选项,可能更适合你。这看起来不错。只是个问题。#ifdef是否只执行一次?我不太熟悉#ifdef。#ifdef…#endif
是预处理器指令。它们在编译时应用一次&以后不再应用。我想这是一个很好的方法。
DO
...
#ifdef <flag>
CALL <subroutine name>
#endif
ENDDO