I have been developing a Fortran application on an Apple Silicon Mac using gfortran. Because there is no debugger that can inspect variables on this platform, occasionally I will compile the code on a windows pc using ifort to fix my crappy code. I really like the debugger environment on that platform (I have tried linux but I personally found gdb inferior) but the problem is my program takes a much longer time to compile with ifort so it is very inefficient.
In windows it takes 5-10 minutes to compile (variation depends on which file I change), while with gfortran it’s never more than 30 seconds, and typically < 10s. I notice there are a handful of flies that seem to be driving the compile time, so I wanted to invest some time in modifying them so they would compile faster, so I can debug faster.
The problem is that I don’t really know how to modify them to reduce compile time. I have seen 3 things in my searches that have been reported to increase compile time:
-having multiple modules in a file
-really large files
-some compiler options
Unfortunately I haven’t found any big levers here. I have split one file into 4 with submodules which didn’t help much, I played around with compiler options, and I only have one module per file.
I don’t think it is the age of the windows processor either. I have a pc with dual boot windows/linux and gfortran on linux is similar to my M1 Mac in terms of compile time, while ifort in windows is super slow.
I was hoping that someone could offer me some tips or point me to some previously existing information so I could more productively try to troubleshoot this. I was hoping to stumble upon a list of factors written down somewhere that can drive up compile time for a single file but I haven’t come across such a document yet. Thanks!
I don’t know if it’s relevant to your code, but gfortran compiles implied do-loops with large bounds slowly. (Does Intel?) For example it takes 7 s on my Windows PC to compile
implicit none
integer, parameter :: n = 10**7, dp = kind(1.0d0)
integer :: i, v(n)
v = [(i, i=1,n)]
print*,sum(real(v, kind=dp))
end
but just 0.1 s for the equivalent program with a do loop.
I am using meson with ninja backend. I am relying on ninja to only recompile the files I need whenever I make a change. I use the same build system on macOS, linux, and windows, and only have the issue with windows/ifort.
I have also just extracted the ifort call for one of the files in question (just from using meson compile --verbose) and played around with compiler options and commenting out code to see if I can get a clue what is going on.
I eventually found that if I take out a call to another module (go from use mod_foo to !use mod_foo) then it compiles super fast. But this just leaves me blindly stabbing in the dark on a different file (mod_foo.f90) so I am wondering if there are some general principles I should know about to help me debug.
Thanks! I don’t have any implied do-loops in the files in question, and I did take a look at the link and played around with character sizes and constants in one of the files I was having trouble with and it had no noticeable impact. But at least I can cross one more thing off the list…
I recall that Intel’s compilers can be slow with compile-time computation, as discussed here. (I guess this is just a more general version of the previously discussed implied do-loops.)
Certain compiler options can make compilation take far longer, as you are aware. I recall that -ipo with ifort can slow down compilation appreciably (same for -flto for ifx). Which compiler options are you using?
Another possibility: This is probably not your problem as what I was doing was far outside normal practice, but I have run into slow compilation times when I had a lot of interfaces (~800 functions). Specifically, I had a program which generated Fortran code including a huge number of derived types and type-bound operators. You can read about the problem on Intel’s forum here, though the bug report focuses on ifort/ifx being unable to compile the code at all, not compilation being slow. As I recall, ifort/ifx would get progressively slower as I added more interfaces/derived types, though I think ifort/ifx didn’t take that long in all cases that would compile. nvfortran was exceedingly slow for this case but would eventually compile the code. In contrast, gfortran and nagfor were quite fast and had no issues.
Thanks for this tip. This was certainly interesting. For my latest compile the longest file took >300s on ifort, but ~1.5 seconds on my Mac. But the file that takes longest to compile on my Mac compiles faster on ifort.
This makes me realize that it way more complicated than I thought to chase down the issues, and maybe I should just learn to do something else while I am compiling on ifort
I am using some debug options on ifort (eg /debug:full and /Od). But before I posted I picked 2 files and did some tests turning off every option and measuring the compile time, and it did not make a major difference. So unless there are compiler options that should be on that reduce compile time significantly it seems the problem is elsewhere.