[PATCH] Improve performance of sinf/cosf/sincosf

Corinna Vinschen vinschen@redhat.com
Mon Jun 18 12:28:00 GMT 2018


On Jun  8 12:49, Wilco Dijkstra wrote:
> This patch is a complete rewrite of sinf, cosf and sincosf.  The new version
> is significantly faster, as well as simple and accurate. 
> The worst-case ULP is 0.56072, maximum relative error is 0.5303p-23 over
> all 4 billion inputs.  In non-nearest rounding modes the error is 1ULP.
> 
> The algorithm uses 3 main cases: small inputs which don't need argument
> reduction, small inputs which need a simple range reduction and large inputs
> requiring complex range reduction.  The code uses approximate integer
> comparisons to quickly decide between these cases - on some targets this may
> be slow, so this can be configured to use floating point comparisons.
> 
> The small range reducer uses a single reduction step to handle values up to
> 120.0.  It is fastest on targets which support inlined round instructions.
> 
> The large range reducer uses integer arithmetic for simplicity.  It does a
> 32x96 bit multiply to compute a 64-bit modulo result.  This is more than
> accurate enough to handle the worst-case cancellation for values close to
> an integer multiple of PI/4.  It could be further optimized, however it is
> already much faster than necessary.
> 
> The speedup factor on AArch64 for various ranges:
> 
> range	0.7853982	sinf	1.7	cosf	2.2	sincosf	2.8
> range	1.570796	sinf	1.9	cosf	1.9	sincosf	2.7
> range	3.141593	sinf	2.0	cosf	2.0	sincosf	3.5
> range	6.283185	sinf	2.3	cosf	2.3	sincosf	4.2
> range	125.6637	sinf	2.9	cosf	3.0	sincosf	5.1
> range	1.1259e15	sinf	26.8	cosf	26.8	sincosf	45.2
> 
> 
> ChangeLog:
> 2018-05-18  Wilco Dijkstra  <wdijkstr@arm.com>
> 
>         * newlib/libm/common/Makefile.in: Regenerated. 	
>         * newlib/libm/common/Makefile.am: Add sf_sin.c, sf_cos.c, sf_sincos.c
>         sf_sincos.h, sf_sincos_data.c. Add -fbuiltin -fno-math-errno to CFLAGS.
>         * newlib/libm/common/math_config.h: Add HAVE_FAST_ROUND, HAVE_FAST_LROUND,
>         roundtoint, converttoint, force_eval_float, force_eval_double, eval_as_float,
>         eval_as_double, likely, unlikely.
>         * newlib/libm/common/sf_cos.c: New file.
>         * newlib/libm/common/sf_sin.c: Likewise.
>         * newlib/libm/common/sf_sincos.h: Likewise.
>         * newlib/libm/common/sf_sincos.c: Likewise.
>         * newlib/libm/common/sf_sincos_data.c: Likewise.
>         * newlib/libm/math/sf_cos.c: Add #if to build conditionally.
>         * newlib/libm/math/sf_sin.c: Likewise.
>         * newlib/libm/math/wf_sincos.c: Likewise.

I tested this patch on Cygwin and it breaks the build:

ld: Cannot export cosf: symbol not defined
ld: Cannot export sinf: symbol not defined
x86_64-pc-cygwin/newlib/libm/libm.a(lib_a-ccosf.o): In function `ccosf':
newlib/libm/complex/ccosf.c:46: undefined reference to `sinf'
newlib/libm/complex/ccosf.c:46:(.text+0x6e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `sinf'
newlib/libm/complex/ccosf.c:46: undefined reference to `cosf'
[etc]

Somehow sinf and cosf disappeard...


Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/newlib/attachments/20180618/a4958b6f/attachment.sig>


More information about the Newlib mailing list