Take the 2-minute tour ×

I'm curious on how quick floating point operations are on dedicated hardware vs fixed.

With fixed point, say you have the number 555 and you want to multiply by 1.54, you'd load the values 555, 154, and 100 into registers (three clocks), multiply 555 by 154 (four clocks), and divide by 100 (four clocks), then load the output register into memory (one clock).

With floating point, you'd load the values 555 and 1.54 into registers (two clocks), get the larger scaling/exponent (one clock), subtract the scalings (one clock), normalize one (four clocks for a multiply), multiply (four clocks), then save the output register into memory (one clock).

12 clocks for fixed and 13 for floating. So am I missing something and there is a real performance benefit or is it all just ease of use? I just used four clocks for multiply, obviously it's not going to be the same on all processors but it gives a general idea.

share|improve this question
Obviously for operations where you don't know the scaling ahead of time and you need to pack it in the number it's crucial to have specialized hardware, but those kind of operations are usually pretty rare... –  Ryan Brown Dec 25 '12 at 7:09
Hmm I didn't take into account bitshifting. On the fixed side you could bit shift instead of dividing by 100 (would have to convert to base 2 instead of base 10). So down to 10 clocks on the fixed side maybe, that one is iffy. Don't think you can do the bit shifting on the floating point since the exponents are all base 10. –  Ryan Brown Dec 25 '12 at 7:21
add comment

2 Answers

Using fixed point numbers 1.54 would be already stored in a proper format for you. You would then need to just do integer multiplication followed by constant addition to compensate for rounding errors and some sifting to get the base correct. See Wikipedia:Q number format.

E.g. assuming Q15.16 format (15 bits for integer, 16 bits for the fractional parts), you could perform the multiplication like this:

int32_t a = 555 * (1 << 16);  /* constant */
int32_t b = 1.54 * (1 << 16); /* constant, no calculations needed at run time */

int64_t temp = ((((int64_t) a) * b) + (1 << 15)) >> 16;
int32_t result = (int32_t) temp;

No division or other calculation is needed to get 1.54 into b (unless you need to read input from outside). With your assumed CPU two loads, double precision multiply, addition by constant (already in register if you perform many multiplications at once), and shift.

With dedicated hardware (e.g. DSP cores or instructions extensions) some Qn.m types would be directly supported, also in vectorized fashion. Though with higher level CPUs (modern Intels or AMDs), I believe there is probably not that much benefit using fixed points as floating point instructions are already very efficient.

share|improve this answer
So down to 9 clocks for a fixed multiply, assuming you even need to retrieve from and save to memory. So are the specialized floating point units there just because programming is so much easier with floating point? –  Ryan Brown Dec 25 '12 at 7:45
I believe it does not matter too much for modern CPUs to use floating points unless you are able to and want to vectorize your computations (e.g. using machine architecture specific gcc intrinsics). Using fixed points is very meaningful if your CPU does not support floats in hardware (e.g. lower end ARM and MIPS). –  FooF Dec 25 '12 at 7:52
add comment

For modern processors, it is not very useful to look at performance of individual instructions. Many are both pipelined and superscalar, so multiple instructions are at various stages of being executed at the same time.

Calculating performance from processor specifications and code is extremely difficult. I would generally only do it to estimate performance of a processor that does not yet exist. If the processor and the code both exist, it is much easier to measure.

share|improve this answer
add comment

Your Answer


