Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: i386 floating point expertise needed



    Date:        Wed, 29 Nov 2017 18:54:27 -0500
    From:        "Terry Moore" <tmm%mcci.com@localhost>
    Message-ID:  <00f601d3696d$6436c8a0$2ca459e0$@mcci.com>

  | I used to have such knowledge. Unfortunately, I don't know Unix-style 
  | 386 assembly, having gained that knowledge in the x86 commercial
  | world; but I don't think that's needed.

No, it shouldn't be.

  | The problem is that the 386 does computations with 80-bit numbers, not
  | 64-bit.   The compiler has evidently optimized out a store that would
  | have forced the truncation.

In the original test, there was no store it was more like

	if (fn("string") != value)
		fail;

Does the i386 function return for floats (doubles) also return more bits
than are expected by the data type?

If so, that would explain things completely.

  | AMD64 doesn't use 80-bit intermediates, so this issue doesn't arise.

Ah, good, that explains that part of the puzzle.

Thanks for the assistance.


Thor Lancelot Simon <tls%panix.com@localhost> said:
  | If this is the cause, it should go away with gcc -ffloat-store.
  | This should be easy to confirm... 

Yes, it should be, and is (I even cunningly confirmed that it was going
to recompile the test with the new option by trying -ffloat_store initially!)

And confirmed, the test works fine with that option used when compiling.

  | I though GCC always stored both operands before a comparison.

gcc keeps getting "smarter" ...

  | I'm not surprised the subtraction test, however, fails.

The subtraction was not part of the original test - I added it as
an initial attempt to fix things, by testing

	if (fabs(fn("string") - value) > 1e-7)
		fail;

which worked fine to make the test succeed, but was objected to on the
grounds that "they should be identical - some standard (IEEE floats
I think) requires it".

After that to collect more data, the subtraction result was saved in a
variable, and printed.   From that it became clear that 1e-7 was far
too big, 1e-12 would have done (and yes, I/we know that it should depend
on the value being tested - but for this test, that is essentially a
constant, O(10^5), so 1e-12 as an absolute is a relative difference of
O(1e-17) and 1e-17 is (if I computed it correctly) something that is
2^-57 approx, so just falls off the edge of a 64 bit float (with 56
mantissa bits).


The question now is what we do about this.

Option 1 would be to force -ffloat-store on compiles of that test on i386
(and delete all the difference code that was added - just return the test
to its original form.)

Option 2 would be to keep the test of the difference being inisgnificant
(the way I originally changed it, but using 1e-12 instead of 1e-7) and adding
a comment to explain why.

Option 3 would be to fix/nobble gcc to get rid of those extra bits whenever
actually using float values on i386 (no idea how easy, or even if it is
possible in general).

This should be partly governed by what the C standards say (about which I
have no idea.)

kre



Home | Main Index | Thread Index | Old Index