Version 1.1 of the Java platform specified strict
rules for floating point semantics, using the IEEE 754 standard for computer
arithmetic. These rules enforced strict bit-by-bit reproducibility of floating
point results across implementations, but significantly impaired floating
point performance in some cases. Version 1.2 relaxed the rules for floating
point semantics, allowing a larger exponent than specified by IEEE 754
standard to be used, in certain situations. This has improved performance
on Intel based platforms, while loosening strict bit-by-bit reproducibility
for floating point values. However, the relaxed rules still impair performance
in many important cases. In particular
a. Java semantics prevent the use
of hardware features such as the Fused Multiply Add (FMA) operation on
systems such as Intel IA64, PowerPC, PA-RISC, and MIPS. The FMA operation
computes a*b+c, where a, b and c are IEEE 754 doubles (or floats); the
result is within 0.5 ulp of the exact answer. The FMA operation does not
round the intermediate product, before performing the addition. Therefore,
the result may be (slightly) different than obtained by computing
the product, rounding back to an IEEE 754 double (resp., float), next performing
the addition. An FMA typically offers twice the throughput of a
multiplication followed by an addition.
b. Java semantics prohibit common
compiler optimizations. Such optimizations transform programs using field
axioms that hold for real arithmetic but that hold only approximately for
floating point arithmetic.
While it is sometimes desirable to maintain strict
bit-by-bit reproducibility of floating point operations, such strictness
is not always required. Floating point arithmetic is an approximation
to real arithmetic, and rounding errors are unavoidable. From a numeric
viewpoint, it is often acceptable to replace a computation with another,
that generates different rounding errors, in order to improve performance
and/or accuracy.
This relaxation of floating-point rules can be adopted in Java,
provided that strict reproducibility can be enforced
when needed, and provided that suitable restrictions are set on implementations.
The Java Grande Numerics Work Group has
discussed several proposals to fix this problem, focusing on proposals
that
a. improve performance of codes without
requiring significant, platform dependent, code rewrite.
b. introduce only limited platform dependence
and only for codes that allow the relaxation of floating-point rules.
c. have limited impact on accuracy.
d. require limited implementation effort,
and negligible implementation effort on platforms that are not affected
by current Java floating point restrictions.
e. add only one additional keyword.
This JSR is based on these proposals.
We propose to add a fastfp floating point
mode. This mode will be associated with methods declared using the fastfp
modifier, similar to the strictfp modifier. A Java compiler will
recognize this keyword and will set accordingly an ACC_FAST bit
flag in the method_info structure for this method. This bit indicates to
the JVM that this method can be executed so as to take best advantage of
the underlying platform floating point hardware, while preserving accuracy.
The detailed specification will define constraints on the behavior of methods
defined using the fastfp modifier, so that different implementation will
produce the same results, up to acceptable rounding errors.
A method that does not have the ACC_FAST
bit set will be interpreted as having the default floating point mode or
the strict floating point mode, if the ACC_STRICT flag is set.
Thus, the behavior of methods not declared using the fastfp modifier
(and the behavior of existing byte code) is not changed by this proposal.
A verification exception will be raised if a method has both ACC_FAST
and ACC_STRICT set.
The default floating point mode is an acceptable
implementation of the fastfp mode, so that JVM's are free to ignore the
ACC_FAST flag.
The fastfp keyword can also be used as a class
modifier, in which case it applies to all methods in the class unless overridden
by method modifiers (Will need to specify whether method modifiers can
always override class modifiers).
A compile time error appears if a method or class
contain both the strictfp and fastfp modifiers.
java.lang.reflect.Method is modified to
provide information on the floating point mode of the method.
The precise meaning of fastfp -- i.e., the extent
to which the behavior of fastfp methods can deviate from the behavior
of default methods -- will be elaborated by the expert group. The following
two options were specifically proposed by the Java Grande Forum:
a. an expression of the form a*b+c can be replaced
by an FMA.
b. floating point operations may be reordered,
assuming floating point arithmetic to be associative.
(a) can be generalized by allowing the replacement
of any sequence of floating point operations by any other computation
that is guaranteed to be at least as accurate as the original sequence
(each output is as close to the precise result as in the original sequence).
(b) can be generalized by allowing the exploitation of additional field
axioms. This list of options is not intended to be exclusive -- other proposals
will be examined.
Implementations will provide information on the
transformations enabled in fastfp mode using (read-only) java.util.Properties
entries for each distinct optimization, e.g.
java.fastfp.fma. An implementation can potentially choose, on
startup, which optimizations it will exploit, and set the property appropriately.
Implementations can provide means of controlling which optimizations are
exploited for a particular run and which property entries are set, e.g.
with command line flags.
|