Vaidyanathan
Vaidyanathan

Reputation: 399

Optimizing the number of times a subroutine is called from a loop

A small question on optimizing a program. The problem is stated as follows

Problem Statement:

The main code has a for/DO loop in which a subroutine is present. The subroutine need or need not be executed depending upon a flag I receive from user.

Obvious Solution:

Simplest way of doing it is using an IF loop to call the subroutine. But then this is time consuming if I have to check for the flag everytime the loop is executed. I am doing molecular dynamics and the number of times the loop will be executed will be of the order of 10^5 .

Qn: Is there a better way to do this, like I say to the program whether the subroutine has to be invoked depending on the flag once and for all? I am coding in Fortran 90. So it would be helpful if something can be said along that lines.

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

Upvotes: 1

Views: 157

Answers (1)

Kyle Kanos
Kyle Kanos

Reputation: 3264

I am not sure that an IF statement is really going to slow down the program, even if called (more than) 100,000 times. You might only end up saving a second or two by restructuring the code (test this though!)

Anyway, if the flag is received at the start of the program, then you'd be able to write your code as

IF(<flag is present>) THEN
   DO
      ...
      CALL <subroutine name>
      ...
   ENDDO
ELSE
   DO
      ...
   ENDDO
ENDIF

where the second DO loop omits the subroutine CALL.


EDIT

As another alternative (that might be cheaper to implement) is to pre-process the data and have the flag keyed in at compile-time. This might make the user a bit annoyed to have to recompile the program when changing the flag, but it'd make your job easier.

Anyway, you'd have something like

    DO
       ...
#ifdef <flag>
       CALL <subroutine name>
#endif
    ENDDO

Upvotes: 3

Related Questions