提交 91c28f61 编写于 作者: N nsz

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
上级 8c6fc860
#include <fenv.h> #include <fenv.h>
#include <math.h> #include <math.h>
/* /* nearbyint is the same as rint, but it must not raise the inexact exception */
rint may raise inexact (and it should not alter the fenv otherwise)
nearbyint must not raise inexact
(according to ieee754r section 7.9 both functions should raise invalid double nearbyint(double x)
when the input is signaling nan, but c99 does not define snan so saving {
and restoring the entire fenv should be fine) #ifdef FE_INEXACT
*/ int e;
double nearbyint(double x) { e = fetestexcept(FE_INEXACT);
fenv_t e; #endif
fegetenv(&e);
x = rint(x); x = rint(x);
fesetenv(&e); #ifdef FE_INEXACT
if (!e)
feclearexcept(FE_INEXACT);
#endif
return x; return x;
} }
#include <fenv.h> #include <fenv.h>
#include <math.h> #include <math.h>
float nearbyintf(float x) { float nearbyintf(float x)
fenv_t e; {
#ifdef FE_INEXACT
int e;
fegetenv(&e); e = fetestexcept(FE_INEXACT);
#endif
x = rintf(x); x = rintf(x);
fesetenv(&e); #ifdef FE_INEXACT
if (!e)
feclearexcept(FE_INEXACT);
#endif
return x; return x;
} }
...@@ -10,11 +10,16 @@ long double nearbyintl(long double x) ...@@ -10,11 +10,16 @@ long double nearbyintl(long double x)
#include <fenv.h> #include <fenv.h>
long double nearbyintl(long double x) long double nearbyintl(long double x)
{ {
fenv_t e; #ifdef FE_INEXACT
int e;
fegetenv(&e); e = fetestexcept(FE_INEXACT);
#endif
x = rintl(x); x = rintl(x);
fesetenv(&e); #ifdef FE_INEXACT
if (!e)
feclearexcept(FE_INEXACT);
#endif
return x; return x;
} }
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册