Skip to main content
gamedev.net
🔒 Locked

Untitled

Started by taz0010 4 replies 850+ views
Original Post
taz0010
taz0010
I have a small program that tests the speed of the various operations - addition, multiplication and division in both integer and floating point formats.

My conclusions on the speed of floating point math seem to be way off, as my CPU is taking very different amounts of time depending on the numbers being multiplied or divided.

My benchmark for testing division speed is:

for(int i=0;i<numOps;i++){		flVal /= 1.01f;	}


The optimiser would only emit actual divide ops if I used FP:precise. FP:fast turned them into multiplication ops. FP:precise took twice as long as FP:fast due to the need to convert back to single precision after every operation. I decided to stick with FP:fast, so the optimiser created the constant 1/1.01 = 0.6834... and multiplied by it throughout. (the loops unrolled to 10 ops per iteration)

Turns out repetedly multiplying a number by 0.6834 is extremely slow on my machine. It took 30 times as long as say, multiplying by 1.00001. This is about 10 times as long as it takes to do floating point division.

Has anyone noticed this before? It has the potential to affect the performance of math intensive code in ways that I didn't realise possible. At least on my machine (Core i7 920)
alvaro
alvaro
Many floating-point operations have a large variation in the possible running time, but on modern processors multiplication shouldn't be one of them.

Quote:
1/1.01 = 0.6834...

What?
MaulingMonkey
MaulingMonkey
Your benchmark numbers sound off -- your optimizer must be doing something significantly different for your two different setups (assuming your benchmark isn't flawed outright somehow). Without seeing benchmark code and assembly, there's not much to talk about.

1/1.01 = 0.9900990099...

[Edited by - MaulingMonkey on June 15, 2010 8:08:29 AM]
Adam_42
Adam_42
I suspect the performance problem you're seeing is caused by denormalized numbers - http://en.wikipedia.org/wiki/Denormal_number

Depending on the CPU they can be noticeably slower than standard numbers, even with hardware support maths with them can run 30 times slower. The same goes for doing calculations with NaN or Infinity values.

Due to rounding issues dividing by 1.01 may never reach zero. Try it with dividing by 2.0f and it should be significantly quicker.
taz0010
taz0010
Solved.

Quote:
Original post by Adam_42
I suspect the performance problem you're seeing is caused by denormalized numbers - http://en.wikipedia.org/wiki/Denormal_number

Depending on the CPU they can be noticeably slower than standard numbers, even with hardware support maths with them can run 30 times slower. The same goes for doing calculations with NaN or Infinity values.

Due to rounding issues dividing by 1.01 may never reach zero. Try it with dividing by 2.0f and it should be significantly quicker.


You're right, denormals were taking far longer to process than other computations. A few quick tests indicate that:

- Denormals slow floating point multiplication down immensely
- Division takes about 5-6 times as long as multiplication, except;
- Dividing infinity by a number only takes 2x as long as multiplying (i.e. it's faster)
- Trivial operations (x*0, 0*0, infinity * (non-infinity)x, etc) run at the same speed as normal operations.

I'm not entirely sure what denormals do. Can someone give me a quick explanation?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.