[PATCH] improves exp() and expf() performance on Sparc.

Patrick McGehearty patrick.mcgehearty@oracle.com
Wed Sep 6 20:34:00 GMT 2017


On 9/1/2017 6:13 PM, Joseph Myers wrote:
> You're defining ifuncs for exp and expf (rather than __ieee754_exp,
> __exp_finite etc. as on x86_64).  But you're not doing anything to stop
> the w_exp_compat / w_expf_compat wrappers from being built that also
> define exp and expf, so I don't see how that can work without ending up
> with multiple definitions of exp and expf; I'd expect you to need to
> override the wrappers with empty files in such a case of a function
> implementation with all the error handling integrated.
The sysdeps/ieee754/dbl-64/w_exp_compat.c
declares __exp (double x)
and then adds:
hidden_def (__exp)
weak_alias (__exp, exp)

I believe the weak_alias in w_exp_compat.c is overriden by the
sparc_libm_ifunc in e_exp-generic.c.  At least, I am not seeing any
link time errors about double exp declarations and I am seeing the new
code being executed (as proved by the speed and accuracy changes).

>
> I'm also concerned that you have local matherr handling which is not
> compatible with all the cases in __kernel_standard (which are not well
> tested).  If you need to have your own integrated error handling for
> performance reasons, matherr handling should be bug-compatible with the
> existing code, for both overflow and underflow.  (Or define a new symbol
> version, make the existing exp and expf into compat symbols for SPARC and
> then your new version only needs to handle errno setting, not matherr.)
>
As for error handling, I believe the extra level of indirection on
return from exp provided by the sysdeps/ieee754/dbl-64/w_exp_compat.c
routine is an anti-performance design. Every normal return from e_exp
requires an extra level of indirection and several tests/branches that
should be bypassed unless an error is detected. The e_exp code already
checks for underflow/overflow/NAN/etc. Those unnecessary tests for the
non-exceptional cases add overhead for the most frequent uses of exp().

On the other hand, once an error occurs that triggers__set_err_exp,
extra overhead is not a significant performance issue. I will add a
call __kernel_standard in that routine when _LIB_VERSION is not _IEEE_
or _POSIX_. As you point out, that will provide more consistent error
handling behavior. I'll make that change in my next exp patch
submission.

- patrick



More information about the Libc-alpha mailing list