This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: What is acceptable for -ffast-math? A numerical viewpoint


<<Speaking as someone with an interest in games programming, I would
_love_ to have an option that tells GCC "apply any transform that would
make sense for true real numbers, and to hell with the last few decimal
places".
>>

Please reread my previous example. The trouble is that "apply any transform
that would make sense for true real numbers" does not just affect "the last
few decimal places", it can have much more radical effects, such as making
all your programs die immediately with overflow errors even if your numbers
are nowhere near the limit of overflow in the canonical evaluation semantics.

Now of course you react by saying, "well of course that's not acceptable", but
then we are left with the situation where you are

a) claiming that the criterion is a simple one, namely allow any
transformation that is allowed for real numbers

b) not willing to accept the consequences of this proposal

Furthermore, do you really mean "the last few decimal places"? Remember that
in 32-bit mode, you only have 6 decimal places of accuracy to start with.

<<This is why I can't understand the position you and Gabriel are taking.
You're acting as though _you_ were going to be forced to use this
option. Since you obviously want last-decimal-place precision,
presumably you're going to use -mieee instead. So why do you care what
the extreme maths option does?
>>

First of all, last decimal place position does not have much to do with
anything, most surely any serious analysis must be in terms of ULP's.
Second, you completely misintepret our position.

Suppose we take the position that we allow any transformation that does
not affect any result by more than X ULP's. Now we can discuss the value
of X, I would guess most people are thinking in terms of a "few" ULP's,
though you seem to be in the range of 50,000 or something like that which
is really radical.

The trouble is that for any value of X, any of the transformations we are
talking about can exceed X in some boundary cases.

Now you probably want to react by saying that you don't care about boundary
cases. Fine, but now you have to define what you mean by boundary cases,
and that, as we know from some of the discussions in the thread, is not
at all easy.

My guess is that a reasonable summary of your position (and others who share
it) is something like:

"do any reasonable transformation that would be OK for real arithmetic, where
reasonable is defined as not affecting my programs significantly, where
significantly is defined as not affecting more than the last bits of accuracy.

The trouble with this approach is

a) we can't easily get people to agree on just how much accuracy can be lost.
Sloppy floating-point programming is one thing, but if you get an answer
printed out that says:

   3.75428

and you turn on -ffast-math, and the answer is

   3.77875

then whether that is informally acceptable will vary greatly from one
person to another.

b) Even if we do agree on some kind of accuracy bound, we still have the
problem that you may turn on -ffast-math and not get any answer at all.
Either all your results are NaN's and infinities, or, depending on the
hardware, you terminate with a floating-point exception.

c) You can't issue an absolute edict against b) happening, because all of
the transformations involved can cause the result of b) in some cases.

d) Even if overflow does not occur, there will be boundary cases in which
the results are radically affected. In other words, your program might 
print a result of

   3.75428

and then you turn on -ffast-math, and you get

   -6.7E+42

e) Again, you can't issue an absolute edict against d) happening, because
all of the transformations can cause the result of d) in some cases.

f) It is hard to agree on, or clearly define, what one means by boundary
cases in which the behaviors of b) and d) are considered acceptable.

Floating-point is difficult. It is not so easy to implement DWIM :-)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]