Compile of derived-type array allocation is very slow

Luke Robison robison@arlut.utexas.edu
Fri Aug 11 16:31:00 GMT 2017


Hello,

I'm looking for a work-around to some very long compile-times we are 
observing in our codebase.  I've isolated the issue to a single allocate 
statement which is allocating an array of derived types.  The variable 
I'm allocating is quite complex, containing many additional layers of 
allocatable derived-types.  I've created a test case that exposes the 
problem, see below for code.

Time is almost exclusively spent in "phase opt and generate" and "tree PTA".

I'm compiling with gcc-7.1 on a pretty old on RHEL5.7, Intel Core 2 @ 
2.5GHz, so these times are probably longer than yours.

command: "gfortran alloc_stress.f90 -O3 -Q -ftime-report -ggdb3"
Results:
level5: 1336. seconds,   1265 MB
level4:   14. seconds,    182 MB
level3:    0.74 seconds,   26 MB
level2:    0.11 seconds,    5 MB

Removing -ggdb3 helps memory, but CPU Time is not significantly affected.

CPU Time is excessive for O3, O2, O1, and O0.  I tested versions 4.2.0, 
4.7.2, 4.8.2 and 7.1.0, and they are all quite slow to compile level4 in 
-O3, with 7.1.0 as the fastest. In 7.1.0 -O3 is actually faster than -O0.

What is happening here?  Why is the top-level allocate so slow to 
compile?  I wouldn't expect initialization for anything other than the 
fields in the structure I'm allocating. What combination of language 
features and compile flags can I use to avoid this?

Thanks,
Luke

=====================
Luke Robison
Engineering Scientist
Applied Research Laboratories: University of Texas at Austin


-8<---------------------
module alloc_stress

type level1
     real, allocatable :: var_r1(:), var_r2(:), var_r3(:), var_r4(:), 
var_r5(:)
     integer, allocatable :: var_i1(:), var_i2(:), var_i3(:), var_i4(:), 
var_i5(:)
     complex, allocatable :: var_c1(:), var_c2(:), var_c3(:), var_c4(:), 
var_c5(:)
     logical, allocatable :: and_this_makes_sixteen(:)
end type level1

type level2
     type(level1), allocatable :: var1(:), var2(:), var3(:), var4(:), 
var5(:)
end type level2

type level3
     type(level2), allocatable :: var1(:), var2(:), var3(:), var4(:), 
var5(:)
end type level3

type level4
     type(level3), allocatable :: var1(:), var2(:), var3(:), var4(:), 
var5(:)
end type level4

type level5
     type(level4), allocatable :: var1(:), var2(:), var3(:), var4(:), 
var5(:)
end type level5

end module alloc_stress

program main
     use alloc_stress
     implicit none
! change this to level 5 if your dare!
     type (level4), allocatable :: foo(:)
     allocate(foo(1))
end program
-8<---------------------



More information about the Fortran mailing list