Long compilation time for recursive data structure access

Long compilation time for recursive data structure access

Hi Steve,

I am seeing very long compilation times, both debug and release, for routines where I am accessing recursive data structures in a certain way.

I have a Type like this:

      Type XYPlot
        SEQUENCE
        Integer(4)                    :: LYR, IA, IB, IG, X, Y, LEVEL
        Character(80)                 :: NAME
        Character(1)                  :: COORD
        Character(7)                  :: CDUMMY
        Type(XYPlot), POINTER         :: Local(:)  ! -- Recursive for MsGMC
      End Type

So it contains a Pointer array of the same data type (this is what I mean by recursive).

which has not been a problem, but, I recently added some references like this (with MicroPlots being of Type XYPlot):

            DO LEV = 0, LEVEL(NCURVE_TOT)
               IF (LEV .EQ. 0) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%IG
               ELSEIF (LEV .EQ. 1) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%IG
               ELSEIF (LEV .EQ. 2) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%IG
               ELSEIF (LEV .EQ. 3) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%IG
               ELSEIF (LEV .EQ. 4) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%IG
               ELSEIF (LEV .EQ. 5) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%IG
               ELSEIF (LEV .EQ. 6) THEN
                  IASEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%IA
                  IBSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%IB
                  IGSEL(LEV, NCURVE_TOT) = MacDeckIn%MicroPlots(I)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%Local(1)%IG
               ELSE 
                  WRITE(NIO, *) 'TOO MANY LEVELS'
                  STOP
               ENDIF

And it now takes a very long time to compile this routine.

Can you please tell me why this might be and if there is a setting that I can change to speed up the compilation?  The subroutine is now taking approx. 30 min to compile, whereas, previously is was 1 second.

I am using Intel Visual Fortran Composer XE 2011.

Thanks much,

---Brett

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

 

Did you have a question for us?  Are you asking if there is an issue with long compilation times?

What compiler version are you using?  What OS and Visual Studio?  How long is long?

Does your code use a lot of MODULES, and are the modules inter-dependent (many USE statements in a deep hierarchy).

Ron

Can you please tell me why this might be and if there is a setting that I can change to speed up the compilation?  The subroutine is now taking approx. 30 min to compile, whereas, previously is was 1 second.

I am using Intel Visual Fortran Composer XE 2011, Windows 7 OS, Visual Studio 2010 Professional.

Yes - many modules with interdependence.

 

Thanks.

I apologize, there must have been a Forum error.  Yesterday when I looked at your thread it was EMPTY.  Today I see your example.

I am not sure what happened.  Let me investigate.

 

ron

Nothing you've shown looks unusual.  To my knowledge, there are no issues around types with embedded pointers to that type.  HOWEVER, there have been some bugs with deeply nested USE statements causing long compilation.  That is what I suspect.  These were mostly fixed in Composer XE 2013 and 2013 SP1 Updates 1 and 2 (and upcoming 3).   There is no quick compiler switch for your 2011 compiler to resolve this, these were bugs in the front end of the compiler parsing the USE statements.

So if you can supply a compilable sample I can run this through several compilers to try to find when and where this was fixed OR file a new bug report.

ron

How about using a loop instead of repeated code. Its better practice and might speed up the compile regardless of compiler issues.

TYPE(XYPlot), POINTER :: PLOT
INTEGER J
DO LEV = 0, LEVEL(NCURVE_TOT)
   IF (LEV > 6) THEN
      WRITE(NIO, *) 'TOO MANY LEVELS'
      STOP
   END IF
   PLOT => MacDeckIn%MicroPlots(I)
   DO J = 1, LEV
      PLOT => PLOT%Local(1)
   END DO
   IASEL(LEV, NCURVE_TOT) = PLOT%IA
   IBSEL(LEV, NCURVE_TOT) = PLOT%IB
   IGSEL(LEV, NCURVE_TOT) = PLOT%IG
END DO

In general a SELECT CASE statement with included CASE and CASE DEFAULT statements is the adequate replacement for the sequence of IF and ELSEIF statements in the original code. The code suggested by Andrew is shorter, maybe faster.

I have run into very impressive compilation times (>20 minutes) when a particular module causes the compiler to use so much memory it has to swap. The specific case was an initialization for a very large string, with the compiler running in a small VM. You could check to make sure that your compiler is not running into a swap condition.

Leave a Comment

Please sign in to add a comment. Not a member? Join today