[comp.arch] Is double->int slow?

umh@vax5.cit.cornell.edu (06/07/91)

I have a set of routines that perform a lot of double-> int conversions. These
are things like I interpolate some real number, then truncate that to use as an
index into an array of pixel values. Anyway profiling tells me that 20% of my
time is spent in these casts of a double to an int. This seems to me very high-
the interpolation and other fiddling are a large part of my code. 

So my point is: is the conversion of a float or double to an int, an inherently
expensive process- ie more than 1 or 2 clocks? Is it normally done in the FPU,
or is it done in software? Or does the C casting of double to int do something
strange over and above the straight conversion- some sort of consistency checks
or such that eat up ti?

For what it's worthm I'm working on an RS/6000, but I'd be interested to hear
about how this is handled under any modern architecture.

Maynard Handley

weaver@jetsun.weitek.COM (Mike Weaver) (06/11/91)

In article <1991Jun6.172905.5304@vax5.cit.cornell.edu> umh@vax5.cit.cornell.edu writes:
>... is the conversion of a float or double to an int, an inherently
>expensive process- ie more than 1 or 2 clocks? Is it normally done in the FPU,
>or is it done in software? Or does the C casting of double to int do something
>strange over and above the straight conversion- some sort of consistency checks
>or such that eat up ti?
>
>For what it's worthm I'm working on an RS/6000, but I'd be interested to hear
>about how this is handled under any modern architecture.
>
>Maynard Handley

I wasn't able to find out about the RS/6000, but a double to int
conversion is not inherently more complicated than a floating point
add. On our (Weitek) hardware, as used in Sun workstations, double to
int and float to int both take the same time as adding two floats or
adding two doubles. Converting the other way is similar, except that
for int to float takes twice as long, because of an extra rounding step
since 32 bits (int) may not fit into the float significand.

However, floating point to/from integer conversions are notorious for
being slow, mostly because they are considered infrequent operations
and therefore not worth much expense in hardware. I would not be
surprised if the conversions were done in software on some present day
machines with generally good floating point performance.

cogswell@MEAT.cs.cmu.edu (Bryce Cogswell) (06/11/91)

Double to int conversion on the RS/6000 is done in software, and
requires 17-39 instructions.

-- Bryce

dik@cwi.nl (Dik T. Winter) (06/12/91)

In article <COGSWELL.91Jun11112827@MEAT.cs.cmu.edu> cogswell@MEAT.cs.cmu.edu (Bryce Cogswell) writes:
 > Double to int conversion on the RS/6000 is done in software, and
 > requires 17-39 instructions.
 > 
Indeed.  But most of the code are for out of range checking end rounding mode
setting (I think).  The actual conversion is only 3 instructions.
--
dik t. winter, cwi, amsterdam, nederland
dik@cwi.nl

cet1@cl.cam.ac.uk (C.E. Thompson) (06/12/91)

In article <COGSWELL.91Jun11112827@MEAT.cs.cmu.edu> cogswell@MEAT.cs.cmu.edu (Bryce Cogswell) writes:
>Double to int conversion on the RS/6000 is done in software, and
>requires 17-39 instructions.
>
That's mind-bogglingly many. If it doesn't violate any legal nicety, could
you post the details?

The tedious aspect of double->int conversion in software is usually the
range check. After that, with an IEEE754 implemnetation, adding a suitable
constant to move the integer part to the low-order bits of the mantissa and
simulataneously bias by 2**31 does the trick.

Chris Thompson
JANET:    cet1@uk.ac.cam.phx
Internet: cet1%phx.cam.ac.uk@nsfnet-relay.ac.uk

hrubin@pop.stat.purdue.edu (Herman Rubin) (06/13/91)

In article <1991Jun12.014037.26495@cl.cam.ac.uk>, cet1@cl.cam.ac.uk (C.E. Thompson) writes:
> In article <COGSWELL.91Jun11112827@MEAT.cs.cmu.edu> cogswell@MEAT.cs.cmu.edu (Bryce Cogswell) writes:
> >Double to int conversion on the RS/6000 is done in software, and
> >requires 17-39 instructions.
> >
> That's mind-bogglingly many. If it doesn't violate any legal nicety, could
> you post the details?
> 
> The tedious aspect of double->int conversion in software is usually the
> range check. After that, with an IEEE754 implemnetation, adding a suitable
> constant to move the integer part to the low-order bits of the mantissa and
> simulataneously bias by 2**31 does the trick.

Range checking is also simple in hardware compared to software.  But ignoring
this, how much is involved?  I am assuming that the situation will be that 
the double number is in a register, and that the integer is wanted in a 
register.

	Add constant to double
	Store result
	Load lower part in integer register
	Toggle sign bit

If it is known that the answer is non-negative, changing the constant
allows ignoring the last step, and also allows one more bit for an
unsigned result.

Converting integer to double is the reverse of this.  And suppose one 
wants the integer and fraction as well as doubles?  This should not
be done as a separate project, but 3 more instructions are needed,
all floating.  This is the also the case if only the fraction is
wanted.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907-1399
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet)   {purdue,pur-ee}!l.cc!hrubin(UUCP)

dik@cwi.nl (Dik T. Winter) (06/14/91)

In article <1991Jun12.014037.26495@cl.cam.ac.uk> cet1@cl.cam.ac.uk (C.E. Thompson) writes:
 > In article <COGSWELL.91Jun11112827@MEAT.cs.cmu.edu> cogswell@MEAT.cs.cmu.edu (Bryce Cogswell) writes:
 > >Double to int conversion on the RS/6000 is done in software, and
 > >requires 17-39 instructions.
 > That's mind-bogglingly many. If it doesn't violate any legal nicety, could
 > you post the details?
I do not think it violates any legal nicety.
 > 
 > The tedious aspect of double->int conversion in software is usually the
 > range check. After that, with an IEEE754 implemnetation, adding a suitable
 > constant to move the integer part to the low-order bits of the mantissa and
 > simulataneously bias by 2**31 does the trick.
On the RS6000 the tedious aspect is not the range check, it is the correctly
setting of the FP status bits.  When running through the code, I do not think
it is done very efficiently.
--
dik t. winter, cwi, amsterdam, nederland
dik@cwi.nl

cogswell@MEAT.cs.cmu.edu (Bryce Cogswell) (06/14/91)

I count 16 instructions used to perform the double -> int conversion on
the RS/6000:
	4 are used for +/- checking and compensation.
	4 are used for range checking.
	4 are used to manipulate the FP status register.
	4 are used to truncate and move the number to an integer register.

The cc compiler calls a subroutine to perform the conversion, so the
actual number of instructions required in C is larger.


As long as I'm wasting bandwidth on this, here is the code sequence:
The double value is initially in f1.  r2 and r6 point to memory containing
constants.  c6 and c0 are condition code registers.

        lfs     f0,12(r2)       f0 <- 0.0
        fcmpu   c6,f1,f0        c6 <- f1 ? f0           [X >= 0]
        l       r6,16(r2)       r6 <- 0x10000778
        fabs    f5,f1           f5 <- abs( f1 )
        lfd     f2,8(r6)        f2 <- 2^31
        mffs    f4              f4 <- floating status
        fcmpu   c0,f5,f2        c0 <- f5 ? f2
        lfd     f3,0(r6)        f3 <- 4512395720392704.0
        bc      12,24,L2        branch if c6 less than [X negative]
        mtfsb1  30              set floating status bit 30
        mtfsb1  31              (re)set floating status bit 31
        fa      f6,f1,f3        f6 <- f1 + f3 [truncates value]
        stfd    f6,-8(r1)       mem <- f6
        mtfsf   1,f4            floating status <- f4
        bc      4,0,L3          branch if c0 greater than [X out of range]
        l       r3,-4(r1)       r3 <- mem

If the double is negative a similar sequence of instructions is executed,
except that bit 31 of the status register is reset rather than set.

-- Bryce