[RFC] [BZ15384] Enchance finite and isfinite.
Ondřej Bílka
neleai@seznam.cz
Fri Apr 26 16:25:00 GMT 2013
On Sun, Apr 21, 2013 at 08:41:33PM +0200, Marc Glisse wrote:
> On Sun, 21 Apr 2013, OndÅej BÃlka wrote:
>
> >On Sun, Apr 21, 2013 at 03:35:19PM +0200, Marc Glisse wrote:
> >>On Sun, 21 Apr 2013, OndÅej BÃlka wrote:
> >>>However on x64 even gcc without optimizations expands finite to inline
> >>>version which is slower than my version(see benchmark).
> >>
Following should generic version be tried on other archs. I could get
20% speedup on sparc on this benchmark.
run with
for i in `seq 0 7`; do echo finite$i; gcc finite_bench.c -O3 -Wall -W -fno-builtin-finite -Dfinite=finite$i; for j in `seq 1 8`; do /usr/bin/time -f "%U" ./a.out; done; done
-------------- next part --------------
#include <stdint.h>
#include <math.h>
typedef union
{
double value;
struct
{
uint32_t lsw;
uint32_t msw;
} parts;
uint64_t word;
} ieee_double_shape_type;
# define GET_HIGH_WORD(i,d) \
do { \
ieee_double_shape_type gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
#define EXTRACT_WORDS64(i, d) \
do { \
ieee_double_shape_type gh_u; \
gh_u.value = (d); \
(i) = gh_u.word; \
} while (0)
int finite0(double x)
{
int32_t hx;
GET_HIGH_WORD(hx,x);
return (int)((uint32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
}
int finite1(double x)
{
int32_t hx;
GET_HIGH_WORD(hx,x);
return (int)((uint32_t)((hx&0x7ff00000)-0x7ff00000)>>31);
}
int finite2(double x)
{
int64_t lx;
EXTRACT_WORDS64(lx,x);
return (int)((uint64_t)((lx&INT64_C(0x7ff0000000000000))-INT64_C(0x7ff0000000000000))>>63);
}
uint64_t finite3(double x)
{
int64_t lx;
EXTRACT_WORDS64(lx,x);
return (lx&INT64_C(0x7ff0000000000000))!=INT64_C(0x7ff0000000000000);
}
int finite4(double x)
{
uint64_t lx;
EXTRACT_WORDS64(lx,x);
lx=lx>>52;
return (((lx&0x7ff)==0x7ff));
}
int finite5(double x)
{
double y=x-x;
return y==y;
}
int finite6(double x)
{
return __builtin_finite(x);
}
int finite7(double x)
{
uint64_t lx;
EXTRACT_WORDS64(lx,x);
lx=lx>>52;
return ((((lx+1)&0x7ff));
}
double finite_wrap(double x) __attribute__((noinline,noclone));
double finite_wrap(double x){
if(finite(x)) return 0;
else return x;
}
int main(){
int i;
int r;
double x=3;
double cnt=0;
for(i=0;i<100000000;i++) {
cnt+=finite_wrap(x);
x+=0.323;
}
if (cnt==1)
return 1;
else return 0;
}
More information about the Libc-alpha
mailing list