With gfortran 4.6 onwards, you run a real risk of invoking software-emulated 128-bit precision floating point operations when you thought you were asking for hardware-supported 64-bit operations. A symptom is that the linker requires -lquadmath
to be added.
See this interesting article for more details:
libquadmath was introduced in GFortran 4.6 which fundamentally changed what the -fdefault-real-8
switch does. Rather than promoting all floating point arithmetic to double precision, it doubles the width of all floating point types, so explicitly typed double precision is converted to quad precision. This quad precision is orders of magnitude slower since it must be done in software, causing binaries built with -fdefault-real-8
to grind to a halt when built with GFortran 4.6 and newer.
The solution is to add -fdefault-double-8
to undo this implicit doubling of explicit real*8.
Guidance
When building ECMWF software which contains Fortran code, if you add -fdefault-real-8
then you should also add -fdefault-double-8
to the compiler flags. If the linker complains about missing quadmath symbols then you may need to rebuild the complete software stack - for example, you may encounter the problem when linking Metview, but the problem might have been generated when building emoslib. For CMake, this command-line option should work:
Code Block | ||
---|---|---|
| ||
cmake ...... -DCMAKE_Fortran_FLAGS="-fdefault-real-8 -fdefault-double-8" |
Addendum
The behaviour can be demonstrated with the following trivial Fortran programme:
Code Block |
---|
program gfortran_test
double precision :: a, b, c
c = a + b
end program |
Compile this programme in 3 variants:
Code Block |
---|
# Default precision
gfortran test.F90 -o test_default
# Double precision for real and double
gfortran test.F90 -fdefault-real-8 -fdefault-double-8 -o test_double8
# Double precision for real, quad precision for double
gfortran test.F90 -fdefault-real-8 -o test_double16 |
Verify that the last programme actually uses emulated quad precision and the remaining ones do not:
Code Block |
---|
$ nm -a test_default | fgrep __addtf3
$ nm -a test_double8 | fgrep __addtf3
$ nm -a test_double16 | fgrep __addtf3
U __addtf3@@GCC_4.3.0 |
Info |
---|
Note that gfortran >= 4.6 will always link libquadmath, regardless of whether quad precision emulation is actually required or not. In other words: if a library / binary links libquadmath, this is not yet a sufficient indication that quad precision double arithmetic is used. |