1

关于优化程序的一个小问题。问题表述如下

问题陈述:

主代码有一个 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
4

1 回答 1

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
于 2013-10-16T16:15:57.953 回答