Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Mar 2008 10:30:14 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Colin Percival <cperciva@FreeBSD.org>
Cc:        cvs-src@FreeBSD.org, src-committers@FreeBSD.org, Bruce Evans <bde@FreeBSD.org>, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/sys/i386/include _types.h
Message-ID:  <20080306095645.V7605@delplex.bde.org>
In-Reply-To: <47CE8396.6020803@freebsd.org>
References:  <200803051121.m25BLE03035426@repoman.freebsd.org> <47CE8396.6020803@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 5 Mar 2008, Colin Percival wrote:

> Bruce Evans wrote:
>>   Modified files:
>>     sys/i386/include     _types.h
>>   Log:
>>   Change float_t and double_t to long double on i386.
>
> Doesn't this have a rather severe performance impact on any code which
> uses double_t?

No.  As mentioned in the commit message, this has no performance effect
except in cases where it avoids compiler bugs.  In fact, I need it
partly to improve performance in cases where other methods of avoiding
the compiler bugs (including fixing the compiler) have a severe
performance effect.  Using a correctly defined double_t makes it
possible for non-broken generated code to operate entirely on registers,
while using plain double requires either broken generated code or
lots of conversions via memory.  E.g.:

 	double x, y, z;
 	z = x + y;

 	Typical wrong generated i386 code for this:
 	fadd	%st(1),%st

 	Non-broken code for this (get it by fixing the compiler or messing
 	up the source code using something like STRICT_ASSIGN()):
 	fadd	%st(1),%st
 	fstpl	mem		# or fstps/flds to convert to float
 	fldl	mem

Using double_t == long double:

 	double_t x, y, z;
 	z = x + y;

 	Typical generated i386 code for this:
 	fadd	%st(1),%st

x and y would probably start out as doubles and be loaded into registers
using fldl.  This gives a long double whether you want it to or not
(all FP registers are long double).  Then the severe performance impact
is from converting the long double back to "double z" on assignment
as is required for C compilers.  OTOH, if you use long double for
memory variables then you get a severe performance impact and some
space loss for the load instruction, since loading long doubles is
much slower than loading doubles (about 4 times slower on Athlons).

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080306095645.V7605>