public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: Sine and Cosine Accuracy
@ 2005-05-28  4:32 Menezes, Evandro
  2005-05-28  5:02 ` Scott Robert Ladd
  2005-05-28 10:44 ` Gary Funck
  0 siblings, 2 replies; 86+ messages in thread
From: Menezes, Evandro @ 2005-05-28  4:32 UTC (permalink / raw)
  To: Scott Robert Ladd; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 2413 bytes --]

Scott, 

> Actually, it tested every 1.8°, but who wants to be picky. 
> I've rerun the test overnight at greater resolution, testing every
> 0.00000018 degress, and saw no change in the result.

That's because the error is the same but symmetrical for sin and cos, so that, when you calculate the sum of their squares, one cancels the other out.

The lack of accuracy in x87 is well known: see http://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html#Errors-in-Math-Functions.

I modified your test slightly to return the number of error bits.  My results using GCC 4.0.0 on an Opteron system running SUSE 9.1 were:

x87sincos-32-fst
cumulative error: 4 (ulp)
                 -5.10702591327572e-15 (decimal)
x87sincos-32-sse
cumulative error: 4 (ulp)
                 -5.10702591327572e-15 (decimal)
x87sincos-32-x87
cumulative error: 2 (ulp)
                  -1.4432899320127e-15 (decimal)
x87sincos-64-sse
cumulative error: 4 (ulp)
                 -4.77395900588817e-15 (decimal)
x87sincos-64-x87
cumulative error: 2 (ulp)
                 -1.22124532708767e-15 (decimal)

On an Athlon MP system running SUSE 9.1:

x87sincos-32-fst
cumulative error: 4 (ulp)
                 -5.10702591327572e-15 (decimal)
x87sincos-32-x87
cumulative error: 2 (ulp)
                  -1.4432899320127e-15 (decimal)

Now, adding -funsafe-math-optimizations, on the same systems:

x87sincos-32-fst
cumulative error: 4 (ulp)
                 -5.10702591327572e-15 (decimal)
x87sincos-32-sse
cumulative error: 4 (ulp)
                 -5.10702591327572e-15 (decimal)
x87sincos-32-x87
cumulative error: 0 (ulp)
                                    +0 (decimal)
x87sincos-64-sse
cumulative error: 4 (ulp)
                 -4.77395900588817e-15 (decimal)
x87sincos-64-x87
cumulative error: 0 (ulp)
                                    +0 (decimal)
And:

x87sincos-32-fst
cumulative error: 4 (ulp)
                 -5.10702591327572e-15 (decimal)
x87sincos-32-x87
cumulative error: 0 (ulp)
                                    +0 (decimal)

Any perceived increase in accuracy in this test comes from intermediary calculations being done with 80 bits and because the errors in fsin are complementary to those in fcos.

HTH


-- 
_______________________________________________________
Evandro Menezes            AMD               Austin, TX

[-- Attachment #2: unsafe.tar.bz2 --]
[-- Type: application/octet-stream, Size: 1227 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread
* RE: Sine and Cosine Accuracy
@ 2005-05-28  6:42 Menezes, Evandro
  0 siblings, 0 replies; 86+ messages in thread
From: Menezes, Evandro @ 2005-05-28  6:42 UTC (permalink / raw)
  To: Scott Robert Ladd; +Cc: gcc

Scott, 

> I still maintain that hardware fsin and fcos are valid and 
> valuable for certain classes of applications,

I agree.  I've just been trying to demonstrate that your test doesn't check sin and cos accuracies, but that sin^2 + cos^2 == 1.  If I had a sin that always returned 1.0 and a cos that always returned 0.0 they would pass your test. :-)

> and that we 
> need better options and documentation -- both of which I'm 
> more than happy to work on. I look forward to your future comments.

By all means, there are many holes in GCC documentation and you've probably tripped at one.  

Yet, I think that enabling x87 transcendentals on x86 only with -funsafe-math-optimizations makes sense, because they're anything but safe: "(a) assume that arguments and results are valid and (b) may violate IEEE or ANSI standards."

And it doesn't make sense to enable them on x86_64 because they're not more optimal than the SSE routines.

Regards,


-- 
_______________________________________________________
Evandro Menezes            AMD               Austin, TX

^ permalink raw reply	[flat|nested] 86+ messages in thread
* RE: Sine and Cosine Accuracy
@ 2005-05-27  0:54 Menezes, Evandro
  2005-05-27  0:54 ` Scott Robert Ladd
  2005-05-27 12:42 ` Scott Robert Ladd
  0 siblings, 2 replies; 86+ messages in thread
From: Menezes, Evandro @ 2005-05-27  0:54 UTC (permalink / raw)
  To: Scott Robert Ladd; +Cc: Richard Henderson, gcc

Scott, 

> > This is not true.  Compare results on an x86 systems with 
> those on an
> > x86_64 or ppc.  As I said before, shortcuts were taken in x87 that 
> > sacrificed accuracy for the sake of speed initially and later of 
> > compatibility.
> 
> It *is* true for the case where the argument is in the range 
> [0, 2*PI), at least according to the tests I published 
> earlier in this thread. If you think there is something 
> erroneous in the test code, I sincerely would like to know.

Your code just tests every 3.6°, perhaps you won't trip at the problems...  

As I said, x87 can be off by hundreds of ulps, whereas the routines for x86_64 which ships with SUSE are accurate to less than 1ulp over their entire domain.

Besides, you're also comparing 80-bit calculations with 64-bit calculations, not only the accuracy of sin and cos.  Try using -ffloat-store along with -mfpmath=387 and see yet another set of results.  At the end of the day, which one do you trust?  I wouldn't trust my check balance to x87 microcode... ;-)

HTH


_______________________________________________________
Evandro Menezes            Software Strategy & Alliance
512-602-9940                                        AMD
evandro.menezes@amd.com                      Austin, TX

^ permalink raw reply	[flat|nested] 86+ messages in thread
* RE: Sine and Cosine Accuracy
@ 2005-05-27  0:39 Menezes, Evandro
  2005-05-27  0:54 ` Scott Robert Ladd
  0 siblings, 1 reply; 86+ messages in thread
From: Menezes, Evandro @ 2005-05-27  0:39 UTC (permalink / raw)
  To: Scott Robert Ladd, Richard Henderson; +Cc: gcc

Scott, 

> For a wide variety of applications, the hardware intrinsics 
> provide both faster and more accurate results, when compared 
> to the library functions.

This is not true.  Compare results on an x86 systems with those on an x86_64 or ppc.  As I said before, shortcuts were taken in x87 that sacrificed accuracy for the sake of speed initially and later of compatibility.

HTH


-- 
_______________________________________________________
Evandro Menezes            AMD               Austin, TX

^ permalink raw reply	[flat|nested] 86+ messages in thread
* RE: Sine and Cosine Accuracy
@ 2005-05-26 23:59 Menezes, Evandro
  2005-05-27 15:19 ` Vincent Lefevre
  0 siblings, 1 reply; 86+ messages in thread
From: Menezes, Evandro @ 2005-05-26 23:59 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: gcc

Uros, 

>   However, the argument to fsin can be reduced to an 
> acceptable range by using fmod builtin. Internally, this 
> builtin is implemented as a very tight loop that check for 
> insufficient reduction, and could reduce whatever finite 
> value one wishes.

Keep in mind that x87 transcendentals are not the most accurate around, but all x86 processors from any manufacturer produce roughly the same results for any argument as the 8087 did way back when, even if the result is hundreds of ulps off...


-- 
_______________________________________________________
Evandro Menezes            AMD               Austin, TX

^ permalink raw reply	[flat|nested] 86+ messages in thread
* Re: Sine and Cosine Accuracy
@ 2005-05-26 23:31 Uros Bizjak
  2005-05-26 23:52 ` Paul Koning
  2005-05-26 23:56 ` Gabriel Dos Reis
  0 siblings, 2 replies; 86+ messages in thread
From: Uros Bizjak @ 2005-05-26 23:31 UTC (permalink / raw)
  To: Paul Koning; +Cc: gcc

Hello!

>Fair enough, so with 64 bit floats you have no right to expect an
>accurate answer for sin(2^90).  However, you DO have a right to expect
>an answer in the range [-1,+1] rather than the 1.2e+27 that Richard
>quoted.  I see no words in the description of
>-funsafe-math-optimizations to lead me to expect such a result.
>
  The source operand to fsin, fcos and fsincos x87 insns must be within 
the range of +-2^63, otherwise a C2 flag is set in FP status word that 
marks insufficient operand reduction. Limited operand range is the 
reason, why fsin & friends are enabled only with 
-funsafe-math-optimizations.

  However, the argument to fsin can be reduced to an acceptable range by 
using fmod builtin. Internally, this builtin is implemented as a very 
tight loop that check for insufficient reduction, and could reduce 
whatever finite value one wishes.

  Out of curiosity, where could sin(2^90) be needed? It looks rather big 
angle to me.

Uros.

^ permalink raw reply	[flat|nested] 86+ messages in thread
* Re: Sine and Cosine Accuracy
@ 2005-05-26 18:38 Morten Welinder
  2005-05-26 20:58 ` Andrew Haley
  0 siblings, 1 reply; 86+ messages in thread
From: Morten Welinder @ 2005-05-26 18:38 UTC (permalink / raw)
  To: gcc, kth

> But, you are using a number in the range of 2^90, only
> have 64 bits for storing the floating point representation, and
> some of that is needed for the exponent.
> 2^90 would require 91 bits for the base alone (as an integer
> value), plus a couple more for the '*PI' portion, and then
> more for the exponent. And that wouldn't include anything
> past the decimal point.
> You are more than 30 bits short of getting a crappy result.

This is not right.

Floating point variables are perfectly capable of holding _some_ rather large
floating point numbers completely accurately.  The integer 2^90 is one of them
(on a standard base-2 machine).

It is true that its nearest neighbours are about 2^30 away, but that is not
relevant for the accuracy of 2^90.  pow(2.0,90.0) generates that value
with no error.

Therefore sin(2^90) is a well defined number somewhere between -1 and 1
and the C fragment

    sin(pow(2.0,90.0))

should calculate it with at most one wrong bit at the end.  (You get a one-bit
allowance since "sin" is trancendental.)

Morten
(who wouldn't be too surprised if some "sin" implementations failed to do that)

^ permalink raw reply	[flat|nested] 86+ messages in thread
* Re: Sine and Cosine Accuracy
@ 2005-05-26 17:53 Morten Welinder
  2005-05-26 18:10 ` Scott Robert Ladd
  0 siblings, 1 reply; 86+ messages in thread
From: Morten Welinder @ 2005-05-26 17:53 UTC (permalink / raw)
  To: gcc

> Yes, but within the defined mathematical ranges for sine and cosine --
> [0, 2 * PI) -- the processor intrinsics are quite accurate.

If you were to look up a serious math book like Abramowitz&Stegun1965
you would see a definition like

    sin z = ((exp(iz)-exp(-iz))/2i                   [4.3.1]

for all complex numbers, thus in particular valid for z=x+0i for all real x.
If you wanted to stick to reals only, a serious math text would probably use
the series expansion around zero [4.3.65]

And there is the answer to your question: if you just think of "sin"
as something
with angles and triangles, then sin(2^90) makes very little sense.  But "sin"
occurs other places where there are no triangles in sight.  For example:

  Gamma(z)Gamma(1-z) = pi/sin(z pi)               [6.1.17]

or in series expansions of the cdf for the Student t distribution [26.7.4]

Morten

^ permalink raw reply	[flat|nested] 86+ messages in thread
* Sine and Cosine Accuracy
@ 2005-05-26 16:05 Scott Robert Ladd
  2005-05-26 16:09 ` Andrew Haley
  2005-05-26 17:23 ` Richard Henderson
  0 siblings, 2 replies; 86+ messages in thread
From: Scott Robert Ladd @ 2005-05-26 16:05 UTC (permalink / raw)
  To: gcc

Let's consider the accuracy of sice and cosine. I've run tests as
follows, using a program provided at the end of this message.

On the Opteron, using GCC 4.0.0 release, the command lines produce these
outputs:

-lm -O3 -march=k8 -funsafe-math-optimizations -mfpmath=387

  generates:
      fsincos

  cumulative accuracy:   60.830074998557684 (binary)
                         18.311677213055471 (decimal)

-lm -O3 -march=k8 -mfpmath=387

  generates:
      call sin
      call cos

  cumulative accuracy:   49.415037499278846 (binary)
                         14.875408524143376 (decimal)

-lm -O3 -march=k8 -funsafe-math-optimizations

  generates:
      call sin
      call cos

  cumulative accuracy:   47.476438043942984 (binary)
                         14.291831938509427 (decimal)

-lm -O3 -march=k8

  generates:
      call sin
      call cos

  cumulative accuracy:   47.476438043942984 (binary)
                         14.291831938509427 (decimal)

The default for Opteron is -mfpmath=sse; as has been discussed in other
threads, this may not be a good choice. I also note that using
-funsafe-math-optimizations (and thus the combined fsincos instruction)
*increases* accuracy.

On the Pentium4, using the same version of GCC, I get:

-lm -O3 -march=pentium4 -funsafe-math-optimizations

  cumulative accuracy:   63.000000000000000 (binary)
                         18.964889726830815 (decimal)

-lm -O3 -march=pentium4

  cumulative accuracy:   49.299560281858909 (binary)
                         14.840646417884166 (decimal)

-lm -O3 -march=pentium4 -funsafe-math-optimizations -mfpmath=sse

  cumulative accuracy:   47.476438043942984 (binary)
                         14.291831938509427 (decimal)

The program used is below. I'm very open to suggestions about this
program, which is a subset of a larger accuracy benchmark I'm writing
(Subtilis).

#include <fenv.h>
#pragma STDC FENV_ACCESS ON
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

static bool verbose = false;
#define PI 3.14159265358979323846

// Test floating point accuracy
inline double binary_accuracy(double x)
{
    return -(log(fabs(x)) / log(2.0));
}

inline double decimal_accuracy(double x)
{
    return -(log(fabs(x)) / log(10.0));
}

// accuracy of trigonometric functions
void trigtest()
{
    static const double range = PI; // * 2.0;
    static const double incr  = PI / 100.0;

    if (verbose)
       printf("          x                diff             accuracy\n");

    double final = 1.0;
    double x;

    for (x = -range; x <= range; x += incr)
    {
        double s1  = sin(x);
        double c1  = cos(x);
        double one = s1 * s1 + c1 * c1;
        double diff = one - 1.0;
        final *= one;

        double accuracy1 = binary_accuracy(diff);

        if (verbose)
            printf("%20.15f %14g %20.15f\n",x,diff,accuracy1);
    }

    final -= 1.0;

    printf("\ncumulative accuracy: %20.15f (binary)\n",
           binary_accuracy(final));

    printf("                     %20.15f (decimal)\n",
           decimal_accuracy(final));
}

// Entry point
int main(int argc, char ** argv)
{
    int i;

    // do we have verbose output?
    if (argc > 1)
    {
        for (i = 1; i < argc; ++i)
        {
            if (!strcmp(argv[i],"-v"))
            {
                verbose = true;
                break;
            }
        }
    }


    // run tests
    trigtest();

    // done
    return 0;
}

..Scott

^ permalink raw reply	[flat|nested] 86+ messages in thread

end of thread, other threads:[~2005-05-31 19:28 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-28  4:32 Sine and Cosine Accuracy Menezes, Evandro
2005-05-28  5:02 ` Scott Robert Ladd
2005-05-28 10:44 ` Gary Funck
  -- strict thread matches above, loose matches on Subject: below --
2005-05-28  6:42 Menezes, Evandro
2005-05-27  0:54 Menezes, Evandro
2005-05-27  0:54 ` Scott Robert Ladd
2005-05-27 12:42 ` Scott Robert Ladd
2005-05-27  0:39 Menezes, Evandro
2005-05-27  0:54 ` Scott Robert Ladd
2005-05-26 23:59 Menezes, Evandro
2005-05-27 15:19 ` Vincent Lefevre
2005-05-26 23:31 Uros Bizjak
2005-05-26 23:52 ` Paul Koning
2005-05-26 23:56 ` Gabriel Dos Reis
2005-05-26 23:57   ` Steven Bosscher
2005-05-27 15:09   ` Olivier Galibert
2005-05-27 15:28     ` Vincent Lefevre
2005-05-27 18:27     ` Marcin Dalecki
2005-05-26 18:38 Morten Welinder
2005-05-26 20:58 ` Andrew Haley
2005-05-26 17:53 Morten Welinder
2005-05-26 18:10 ` Scott Robert Ladd
2005-05-26 18:22   ` Dave Korn
2005-05-26 18:49     ` Scott Robert Ladd
2005-05-26 19:28       ` Dave Korn
2005-05-26 16:05 Scott Robert Ladd
2005-05-26 16:09 ` Andrew Haley
2005-05-26 16:33   ` Scott Robert Ladd
2005-05-26 17:14     ` Andrew Haley
2005-05-26 17:01   ` Paolo Carlini
2005-05-26 17:23 ` Richard Henderson
2005-05-26 17:24   ` Scott Robert Ladd
2005-05-26 17:27     ` Paul Koning
2005-05-26 17:27       ` Scott Robert Ladd
2005-05-26 17:29         ` Dave Korn
2005-05-26 17:37           ` David Daney
2005-05-26 17:56             ` Dave Korn
2005-05-26 17:40           ` Scott Robert Ladd
2005-05-26 18:12             ` Paul Koning
2005-05-26 18:32               ` Scott Robert Ladd
2005-05-26 18:50                 ` Paul Koning
2005-05-26 19:14                   ` Andrew Pinski
2005-05-26 19:35                     ` Scott Robert Ladd
2005-05-29  6:22                   ` Geoffrey Keating
2005-05-31 14:34                     ` Paul Koning
2005-05-31 22:58                       ` Geoff Keating
2005-05-29 12:07                 ` Roger Sayle
2005-05-30 15:34                   ` Vincent Lefevre
2005-05-29  2:22         ` Kai Henningsen
2005-05-29 18:16         ` Marc Espie
2005-05-29 20:58           ` Georg Bauhaus
2005-05-30 15:19             ` Marc Espie
2005-05-30 17:26               ` Scott Robert Ladd
2005-05-30 17:18                 ` Marc Espie
2005-05-30 18:11                   ` Scott Robert Ladd
2005-05-30 17:31               ` Scott Robert Ladd
2005-05-31  3:10                 ` chris jefferson
2005-05-31 12:17                   ` Andrew Haley
2005-05-31 12:46                   ` Scott Robert Ladd
2005-05-31 13:02                     ` Andrew Haley
2005-05-31 13:34                 ` Vincent Lefevre
2005-05-30 15:19             ` Gabriel Dos Reis
2005-05-30 15:35             ` Bernhard R. Link
2005-05-30 18:59               ` Scott Robert Ladd
2005-05-30 19:16               ` Georg Bauhaus
2005-05-30 19:17                 ` Bernhard R. Link
2005-05-30 19:54                   ` Georg Bauhaus
2005-05-30 20:04                     ` Gabriel Dos Reis
2005-05-26 17:35       ` Kevin Handy
2005-05-26 17:41         ` Paul Koning
2005-05-26 20:26           ` Joseph S. Myers
2005-05-26 21:15     ` Gabriel Dos Reis
2005-05-26 21:17       ` Scott Robert Ladd
2005-05-26 23:25         ` Gabriel Dos Reis
2005-05-27  0:18           ` Scott Robert Ladd
2005-05-27  0:54             ` Gabriel Dos Reis
2005-05-27 11:29           ` Marcin Dalecki
2005-05-27  9:36         ` Marcin Dalecki
2005-05-27 10:48       ` Marcin Dalecki
2005-05-26 21:33     ` Richard Henderson
2005-05-27  0:05       ` Scott Robert Ladd
2005-05-27  0:43         ` Gabriel Dos Reis
2005-05-27  0:54           ` Scott Robert Ladd
2005-05-28 11:26             ` Russ Allbery
2005-05-27 13:56     ` Vincent Lefevre
2005-05-29  3:36   ` Kai Henningsen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).