关于优化程序的一个小问题。问题陈述如下
问题陈述:
主代码有一个for / DO循环,其中存在子程序。子程序需要或不需要执行,具体取决于我从用户收到的标志。
明显的解决方案:
最简单的方法是使用IF循环来调用子程序。但是,如果每次执行循环时都必须检查标志,那么这很费时间。我正在进行分子动力学,循环执行的次数将是10 ^ 5的数量级。
问:有没有更好的方法来做到这一点,就像我对程序说,是否必须根据标志一劳永逸地调用子程序?我正在使用Fortran 90进行编码。因此,如果能够说出这些内容,那将会很有帮助。
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
答案 0 :(得分:3)
我不确定IF
语句是否真的会减慢程序的速度,即使被调用(超过)100,000次。你可能只会通过重组代码来节省一两秒(尽管测试一下!)
无论如何,如果在程序开始时收到标志,那么你就可以编写代码
IF(<flag is present>) THEN
DO
...
CALL <subroutine name>
...
ENDDO
ELSE
DO
...
ENDDO
ENDIF
其中第二个DO
循环省略了子例程CALL
。
修改强>
另一种选择(实现起来可能更便宜)是预处理数据并在编译时键入标记。这可能会让用户在更改标志时不得不重新编译程序,但它会让您的工作更轻松。
无论如何,你有类似
的东西 DO
...
#ifdef <flag>
CALL <subroutine name>
#endif
ENDDO