[ET Trac] [Einstein Toolkit] #1563: Provide always-working isnan etc.
Einstein Toolkit
trac-noreply at einsteintoolkit.org
Sat Apr 19 05:33:13 CDT 2014
#1563: Provide always-working isnan etc.
--------------------------+-------------------------------------------------
Reporter: eschnett | Owner:
Type: enhancement | Status: reopened
Priority: major | Milestone:
Component: Cactus | Version: development version
Resolution: | Keywords:
--------------------------+-------------------------------------------------
Comment (by eschnett):
Compiler optimizations are usually not specified via a set of
transformations that are allowed, but rather via a set of properties that
the compiler can assume are valid in any program it sees, and that it
needs to preserve when it generates machine code. By default, such a
property is that the source code adheres to the IEEE floating point
standard, and the compiler thus preserves the meaning of the source code.
(We all know that this standard is too strict for us.)
Thus there is -ffast-math, which means that we use a looser floating point
standard where we do not care about "proper" behaviour of nans. For
example, fmax(nan, 1.0) should return 1.0 ("man fmax"). Implementing this
correctly requires checking each argument whether it is nan before
actually performing the comparison to see which argument is larger, as in:
{{{
inline double fmax(double x, double y)
{
if (isnan(x)) return y;
if (isnan(y)) return x;
return x>=y ? x : y;
}
}}}
Since we want fast code, we tell the compiler that we don't care about
correct behaviour for nans. One of the easiest and most systematic ways to
do this is to simply say that isnan and isinf never return true. This will
automatically avoid all special cases for inf and nan, leading to faster
code.
Of course you may say "I only want to optimize out the isnan calls that I
didn't write myself", but that is difficult to judge for the compiler. The
compiler -- in particular in C++, where almost all of the standard library
exists as header files that are compiled as needed, together with the
application code -- cannot tell whether a particular isnan call has been
inserted into a standard function (and should be omitted), or has been
inserted into a error-checking function (and needs to be kept). For the
compiler, either nans need to be treated as specified in the source code
(keep the isnan calls), or whether it can optimize out the nan-handling
cases (assume isnan is always false).
One could, conceivably, have two kinds of isnan calls: the "annoying" once
in fmax that should be omitted, and the "important" ones that we write in
NaNChecker. Alas, the C and C++ standards don't make that distinction,
they only specify one kind of isnan, namely the one that should always be
kept. There is not even a proper specification of floating point numbers
when -ffast-math is used. Thus, we need to roll our own "never-remove"
isnan calls.
We could try to find compiler options (that's highly compiler specific)
that ignore certain IEEE properties (associativity, reciprocal) while
keeping others (nan behaviour of fmax etc.). I don't think it's
worthwhile.
--
Ticket URL: <https://trac.einsteintoolkit.org/ticket/1563#comment:5>
Einstein Toolkit <http://einsteintoolkit.org>
The Einstein Toolkit
More information about the Trac
mailing list