[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