The -fp-model (Linux* and Mac OS* X) or /fp (Windows*) option allows you to control the optimizations on floating-point data. You can use this option to tune the performance, level of accuracy, or result consistency across platforms for floating-point applications.
For applications that do not require support for denormalized numbers, the -fp-model or /fp option can be combined with the -ftz (Linux*and Mac OS* X) or /Qftz (Windows*) option to flush denormalized results to zero in order to obtain improved runtime performance on processors based on:
You can use keywords to specify the semantics to be used. Possible values of the keywords are as follows:
Keyword |
Description |
---|---|
precise |
Enables value-safe optimizations on floating-point data and rounds intermediate results to source-defined precision. |
fast[=1|2] |
Enables more aggressive optimizations on floating-point data. |
strict |
Enables precise and except, disables contractions, and enables the property that allows modification of the floating-point environment. |
source |
Enables value-safe optimizations on floating-point data and rounds intermediate results to source-defined precision (same as precise keyword). |
double |
Rounds intermediate results to 53-bit (double) precision and enables value-safe optimizations. |
extended |
Rounds intermediate results to 64-bit (extended) precision and enables value-safe optimizations. |
[no-]except (Linux* and Mac OS* X) or |
Determines whether floating-point exception semantics are used. |
The default value of the option is -fp-model fast=1 or /fp:fast=1, which means that the compiler uses more aggressive optimizations on floating-point calculations.
Using the default option keyword -fp-model fast or /fp:fast, you may get significant differences in your result depending on whether the compiler uses x87 or SSE2 instructions to implement floating-point operations. Results are more consistent when the other option keywords are used.
Several examples are provided to illustrate the usage of the keywords. These examples show:
A small example of source code
Note that the same source code is considered in all the included examples.
The semantics that are used to interpret floating-point calculations in the source code
One or more possible ways the compiler may interpret the source code
Note that there are several ways the compiler may interpret the code; we show just some of these possibilities.
Example source code:
REAL T0, T1, T2;
...
T0 = 4.0E + 0.1E + T1 + T2;
When this option is specified, the compiler applies the following semantics:
Additions may be performed in any order
Intermediate expressions may use single, double, or extended double precision
The constant addition may be pre-computed, assuming the default rounding mode
Using these semantics, the following shows some possible ways the compiler may interpret the original code:
REAL T0, T1, T2;
...
T0 = (T1 + T2) + 4.1E;
REAL T0, T1, T2;
...
T0 = (T1 + 4.1E) + T2;
This setting is equivalent to -fp-model precise or /fp:precise on systems based on the IntelĀ® 64 architecture.
Example source code:
REAL T0, T1, T2;
...
T0 = 4.0E + 0.1E + T1 + T2;
When this option is specified, the compiler applies the following semantics:
Additions are performed in program order, taking into account any parentheses
Intermediate expressions use the precision specified in the source code
The constant addition may be pre-computed, assuming the default rounding mode
Using these semantics, the following shows a possible way the compiler may interpret the original code:
REAL T0, T1, T2;
...
T0 = ((4.1E + T1) + T2);
Example source code:
REAL T0, T1, T2;
...
T0 = 4.0E + 0.1E + T1 + T2;
When this option is specified, the compiler applies the following semantics:
Additions are performed in program order, taking into account any parentheses
Intermediate expressions use the precision specified in the source code. In Fortran, intermediate expressions always use source precision in modes other than fast.
The constant addition will not be pre-computed, because there is no way to tell what rounding mode will be active when the program runs.
Using these semantics, the following shows a possible way the compiler may interpret the original code:
REAL T0, T1, T2;
...
T0 = REAL ((((REAL)4.0E + (REAL)0.1E) + (REAL)T1) + (REAL)T2);