When compiling VASP, I am wondering why the

 OFLAG = -O2

is suggested as default. For performance reason, I would use

 OFLAG = -O3

Could someone help explain the reason?

EDIT: I asked this question because I used the DFT code FHI-aims, whose compilation is suggested with optimization level:

FFLAGS = -O3 -ip -fp-model precise
In addition, I use intel compiler.

1 Answer 1


This is a great question! Only a VASP developer involved in making that decision would be able to tell you precisely why they made that decision, but I will give you as many useful pieces of information related to this topic as I can. Many of these are from a 10-year old thread in StackOverflow that currently has 144,000+ views: "Is optimisation level -O3 dangerous in g++?"

  • Applying -O3 to an entire program that is as large as VASP, can cause it to run slower because it would generate more machine code than -O2 which would then make the program unable to fit in the L1 cache. For "large" programs this can also be true for -O2 vs -O1 or -O0. VASP is a "large" program, but I don't know if it's large enough for -O2 to cause this type of slow-down (hopefully the developers who decided to set -O2 to be the default, considered this carefully enough). The intended use of -O3 is that you manually apply it to a small number of files if they contain critical inner loops that actually benefit from these aggressive space-for-speed tradeoffs.

  • -O3 has also been known to have many bugs in the past, but the most upvoted answer in the linked StackOverflow thread says that this was "over a decade ago" (and since that answer was written in July 2012, it would now be over "two decades ago" that this was a problem). It's possible that the tendency for -O3 to have bugs was a factor 20+ years ago in making the decision to make -O2 the default. However, while the top-voted answer in that thread says that the bugs were only a problem 20+ years before 2022, an answer in 2016 from a compiler developer, says that it was still a problem recently.

  • -O3 generally will make compilation take longer (often by a very significant amount), and will make the size of the overall program's executables take up much more space. For a big program like VASP, space can be a concern, and even the time to compile can be a concern (a much smaller program called has sometimes taken me more than 24 hours to compile, which can be enough for your compilation to be interrupted/cut-off due to it being a "job" that takes too long on a shared supercomputer). The longer compile time and larger space required for -O3 in VASP is probably insignificant when compared to the amount of time that VASP is being run (i.e. the use that you're getting out of the compilation), but certainly for smaller programs like my FeynDyn software for numerical Feynman integrals for quantum dynamics, I chose a lot of default settings with the overall user experience in mind rather than only the speed and accuracy of the calculations. I would rather them be able to get started very quickly and without trouble (i.e. bugs in using -O3 and time/space increases causes by -O3 would not be preferred) than to have slightly faster calculations in a program that is already super fast for most calculations no matter what level of optimization is used. This bullet point applies to most scientific software in general rather than just to VASP.

  • Optimization often requires care and attention rather than just blindly using the command with the largest number in it. In this thread where someone was complaining about a bubble sort program being slower with -O3 when compared to -O2, someone posted the following code timings:

-O2 -g: 1.07s
-O3 -g: 1.17s
-O3 -g -fprofile-generate/use: 0.84s
  • 1
    $\begingroup$ (Also, in the Pentium 4 days, I-cache footprint was even more importnat because the legacy decoders were slow and the trace cache was small. It's still much better for current CPUs for code fetch to hit in the L1i or preferably the uop cache, but even L2 hits aren't a disaster if branch prediction is working well, so code fetch is pretty far ahead of execution, keeping the out-of-order window full of work to pick from.) $\endgroup$ Aug 3, 2022 at 21:24
  • 2
    $\begingroup$ I'm not familiar with VASP specifically, but most numerical / scientific computing code spends most of its time in a few loops (small code footprint), so optimizing the crap out of them is worth it. Especially auto-vectorization can be a big win, if it's not already enabled at -O2 with #pragma omp simd ... and -fopenmp to enable that. Even if you get some I-cache misses, that can be worth it if it's once at the start of a new phase of the program, starting a new loop. $\endgroup$ Aug 3, 2022 at 21:28
  • 1
    $\begingroup$ @PeterCordes I think these comments provide some really good insight and it would be useful to future users to have them put into an answer. $\endgroup$
    – Tyberius
    Aug 4, 2022 at 1:09
  • 1
    $\begingroup$ Another possible reason is that many (sometimes most) operations of a scientific calculation program are spent in BLAS, LAPACK and FFT routines, for which one usually calls precompiled, highly optimized libraries regardless of to what extent the main program is optimized. VASP certainly belongs to this category. On the other hand, in molecular codes, such as BDF that I've been working on, the rate-determining step (calculation of two-electron integrals over Gaussian functions) is mostly in explicit loops, so I've seen ~2x speedups when going from -O2 to -Ofast, at least on some platforms. $\endgroup$
    – wzkchem5
    Aug 4, 2022 at 8:04
  • 2
    $\begingroup$ +1 An interesting information I have seen in compilation instructions of many programs is that they recommend -O2 for gcc/gfortran, but -O3 for intel c++ or fortran, because apparently intel's -O3 is more stable. $\endgroup$
    – S R Maiti
    Aug 4, 2022 at 9:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .