nearbyint optimization (only clear inexact when necessary)
old code saved/restored the fenv (the new code is only as slow as that when inexact is not set before the call, but some other flag is set and the rounding is inexact, which is rare) before: bench_nearbyint_exact 5000000 N 261 ns/op bench_nearbyint_inexact_set 5000000 N 262 ns/op bench_nearbyint_inexact_unset 5000000 N 261 ns/op after: bench_nearbyint_exact 10000000 N 94.99 ns/op bench_nearbyint_inexact_set 25000000 N 65.81 ns/op bench_nearbyint_inexact_unset 10000000 N 94.97 ns/op
This commit is contained in:
parent
8c6fc860a9
commit
91c28f61f4
3 changed files with 29 additions and 19 deletions
|
|
@ -1,20 +1,19 @@
|
|||
#include <fenv.h>
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
rint may raise inexact (and it should not alter the fenv otherwise)
|
||||
nearbyint must not raise inexact
|
||||
/* nearbyint is the same as rint, but it must not raise the inexact exception */
|
||||
|
||||
(according to ieee754r section 7.9 both functions should raise invalid
|
||||
when the input is signaling nan, but c99 does not define snan so saving
|
||||
and restoring the entire fenv should be fine)
|
||||
*/
|
||||
double nearbyint(double x)
|
||||
{
|
||||
#ifdef FE_INEXACT
|
||||
int e;
|
||||
|
||||
double nearbyint(double x) {
|
||||
fenv_t e;
|
||||
|
||||
fegetenv(&e);
|
||||
e = fetestexcept(FE_INEXACT);
|
||||
#endif
|
||||
x = rint(x);
|
||||
fesetenv(&e);
|
||||
#ifdef FE_INEXACT
|
||||
if (!e)
|
||||
feclearexcept(FE_INEXACT);
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
#include <fenv.h>
|
||||
#include <math.h>
|
||||
|
||||
float nearbyintf(float x) {
|
||||
fenv_t e;
|
||||
float nearbyintf(float x)
|
||||
{
|
||||
#ifdef FE_INEXACT
|
||||
int e;
|
||||
|
||||
fegetenv(&e);
|
||||
e = fetestexcept(FE_INEXACT);
|
||||
#endif
|
||||
x = rintf(x);
|
||||
fesetenv(&e);
|
||||
#ifdef FE_INEXACT
|
||||
if (!e)
|
||||
feclearexcept(FE_INEXACT);
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,16 @@ long double nearbyintl(long double x)
|
|||
#include <fenv.h>
|
||||
long double nearbyintl(long double x)
|
||||
{
|
||||
fenv_t e;
|
||||
#ifdef FE_INEXACT
|
||||
int e;
|
||||
|
||||
fegetenv(&e);
|
||||
e = fetestexcept(FE_INEXACT);
|
||||
#endif
|
||||
x = rintl(x);
|
||||
fesetenv(&e);
|
||||
#ifdef FE_INEXACT
|
||||
if (!e)
|
||||
feclearexcept(FE_INEXACT);
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue