/2 or *0.5 ?

yanomano's picture

With a lot of maths what is the more rapid : Divide by integers or multiply by floats ?

With maths expressions is there favours to split operations in parallel if it is possible or keep long complex serial formulas ?

Thanks For Advices about Processor(s) calculation...:)

cwright's picture
too abstract

In classical C programming (and a bit in JS, if you work it right), multiplication by a float is faster than integer division (except for some special cases: powers of 2 are very easy to divide by, as are very large values, since the integer divider unit can toss out almost all the bits if the numbers are very close, leaving very few bits to work on). When it comes to performing operations though, it's probably converting them all the floats or arbitrary-precision numbers anyway, where mult will be faster.

In a more interpreted environment though, it's not always so clear. The interpreter can change things behind the scenes, and there's a lot of overhead with interpretation/parsing.

With the math expression patch, I'm pretty sure it won't matter. If you're doing enough math for there to be an appreciable difference, you've probably done something crazy to have that many math patches in a composition :)

As far as I can tell, there's no parallel evaluation for the math (it's very unlikely to give any benefit with such simple operations), but if you can keep it all in a single patch, you'll save a lot of parsing/evaluating setup overhead (compared to using several math expression patches).

yanomano's picture
Very concrete reply :)

Thanks Christopher So in theory it should be more fast to assemble complex formula in a single patch and subtitute multiply to divide...

yanomano.

psonice's picture
*0.5 or /2.0?

Same question, but with added shader bling :)

This makes a lot more of a difference in shaders, as the calculation might get done millions of times per frame. So, which is faster, assuming both are done with floats?

cwright's picture
recip-mult

in this case (shaders are compiled, not interpreted), reciprocal multiplication is the way to go.

The only exception would be dividing by a non-constant (i.e. user input).

For example:

someFloat /= 42.0; someFloat *= 1.0/42.0;

the latter will be faster, since 1/42.0 is a constant, and the compiler will turn it into whatever it is (0.023 or so). I'm guessing that most shader compilers will turn the top one into that too though...

but now this:

someFloat /= userFloat;

vs.

intermediateFloat = 1.0 / userFloat; someFloat *= intermediateFloat;

the latter may be a bit slower (or, again, identical, assuming a smart compiler).

Internally, the shader compiler will probably do the latter if you divide several values by userFloat, (since it'll recover the division losses after a few more multiplies), or the former if that's the only division (since there's no point in doing a divide and a multiply when you can just do a divide...)

As always with performance, profile profile profile, and then pick the best one.

[as a random sample point, gcc has been silently throwing in reciprocal multiplies in place of divides since 3.0 or earlier when faced with a constant in the divisor, in the late 90's... I'm guessing ati/nvidia/intel are clever enough to do that in the compiler too, so this probably won't matter nearly as much as you're hoping...]

[fun twist: many gpu's don't have the ability to do arbitrary division, they do a recip and then a multiply anyway (which doubles your FP error, for those keeping score at home) or they resort to some other inexact approximation. So I'm guessing that the difference between * and / in GLSL is superfluous at best. http://www.cs.unc.edu/~ibr/projects/paranoia/ ]

psonice's picture
Perfect answer, thanks!

Some of my shaders feature a lot of / (which is why I asked), but mostly on texture data which will be non-static. Hmm.. maybe I should re-write those parts. Or at least re-write a bit, and give it a really nasty test case so the difference if any is measurable. One more thing added to the to-do list :)

Thanks for the reply, informative and complete as ever!