On Tue, Sep 26, 2017 at 6:27 AM, Jan Stary <[email protected]> wrote:

> s_sin.c normalizes the argument to [-pi/4, +pi/4].
> This is how |x| <= pi/4 is tested:
>         GET_HIGH_WORD(ix,x);
>         ix &= 0x7fffffff;
>         if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
>
> Why is it done like that? Is it faster or more portable
> or in any way better that comparing the value itself to M_PI_4?
>

See  s_cos.c  s_tan.c;   and many others start with a similar block.
Probably the integer comparison is efficient (fewer average CPU and bus
resources per second tied up per operation).   It will  depend upon your
computer's  characteristics,  and  applications running, and how many times
per second  sin()  is  invoked   on average.

Assuming the compiler optimization of the above code block is as good as it
could be:
that should hinge on whether a single integer copy, and 32-bit integer
subtraction
and Bitwise AND on your CPU will burn more processor work cycles than  two
floating-point copy,
two  floating-point subtraction plus   one  sign negate  operation against
IEEE 64-bit double.

The basic rule of thumb says  that if a  performance-significant task can
be completed using Integers
instead, then maximum effort should be made to avoid/minimize unnecessary
usage of
floating-point operations      (without an excessive increase in the # of
operations),


As  3 to 4 times the processor work cycles for execution path to
 3-argument  64-bit floating point
calculation Versus the corresponding 3-argument operation using 32-bit
integers.

More floating point operations/sec = lower system efficiency,  or
less-effective use of the overall available
compute capacity     Versus   the use of  processors'  regular,  typically
more-optimized ALU pipelines.

> if (-M_PI_4 < x && x < M_PI_4)


> >For Inf and NaN arguments, NaN is returned as follows:
> >        /* sin(Inf or NaN) is NaN */
> >        else if (ix>=0x7ff00000) return x-x;
>


> > Again, why the integer conversion? Would
> >
> >        else if (isinf(x) || isnan(x))


> Also, is "return x-x" just a fast/clever way to return NaN
>

Well,  the original code is applying a >=  test,    whereas isinf() and
isnan() are
shown to be equality  tests  that check for two specific values of the
exponent field.
The  ||  branching is involving more computations though....

General application code should  use  the new  isinf(),  isnan(),   and
nan("")  macros,
but they have not always been part of the C standard,  and I imagine this
code predates it.

The  NaN/InF values are  runtime-specific in the current C standard,   so
it is
only sort of legitimate to do that,   Because  this  code is part of the
 libc runtime's
implementation itself.....

In this context,   the libc implementation has enough information to safely
rely
on the assumption to make the decision without resorting to a macro call
 that
invokes a number of other operations,   and so

Is free  and perfectly fine  to use that   ix >= 0x7ff00000  to  equate
to a  NaN  condition.

That appears to potentially streamline the number of computations required
for this case,
so there  might actually be a performance benefit to not use the macros
here as well.

-- 
-JH

Reply via email to