float unlimited increasing rotation or use a if

Started by
52 comments, last by fir 10 years, 3 months ago

Hi all, i have a question :

suppose i am making a wheel rotating :

float rot = 0.0f;

// in loop

rot += fElapsedtime;

it works fine like this, but the number gets unlimited bigger and bigger.

Now what is better for CPU performance?, using a if that limits the rotation ? :

// in loop

rot += fElapsedtime;

if( rot > Pi )rot -= Pi;

What is the better choise and why ?

thanks in advance

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

Advertisement

What i usually do is something like this

float rot = 0.0f;

rot += somevalue * ElapsedTime;

while(rot >= 360.0f){

Rot -= 360,0f;

if(Rot < 0.0f)

Rot = 0.0f;

}

You should not worrie too much about performance for such simple things. You might loose 1/1000000000 of a second using this algorithm instead of a simpler one, so it's just not worth the trouble. This code handle all wrong/worst case scenario, and that's what matter. You might consider wraping that code to a function tho, if you plan to use it a lot.

The reason im using a while loop is, suppose the frame rate drop because of reason x and 3 seconds have elapsed since the last frame, this will still give a value between 0.0f and 360.0f. The if inside the loop is to protect value < 0.0 in case of a floating point precision error.

Could this also be achieved using float unrolledRot=fmod(absoluteRot, 360.0f)?

o3o

I,m sorry i have no clue what you mean.

It also seems very CPU intensive, using a function like fmod ? ( i dont know what its for )

Normally i dont use functions like : sin() , cos() etc, fmod() looks something like that, very cpu intensive.

Note : i usually avoid divide to.

I,m asking to go with or without the if, and why ?

greetings

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

To represent a rotation I prefer to use a unit-length vector instead of an angle. You can think of it as (cos(angle),sin(angle)). Now a particular rotation only has one possible representation so the issue doesn't exist. Whenever you are going to use the angle, chances are you are going to be computing its sine and cosine anyway, so it's not like we have complicated things.

If you are comfortable with complex numbers, it might be even better to represent the rotation as a complex number with modulus 1.

Complex rot(1.0f, 0.0f);

// in loop
rot *= exp(Complex(0.0f,fElapsedtime));
EDIT: You probably want to renormalize the rotation every so often, like this:
rot /= abs(rot);

Hi there, seems very cpu intensive + i have no clue about complex, and why use exp, the rotation is linear right ? ( it rotates good in screen so i bet );

I mean : i just have a wheel or circlesaw rotating.

float rot = 0.0;

// in loop

{

rot += fElapsedtime;

// now i wanto know if its better to use this :

if( rot > Pi )rot -= Pi;

// otherwise the float rot will be increasing unlimited, i dont know how if affects the cpu;

}

So my question is :

What is more CPU intensive, having the if, or having the huge float numbers ?

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

Hi there, seems very cpu intensive + i have no clue about complex, and why use exp, the rotation is linear right ? ( it rotates good in screen so i bet );
I mean : i just have a wheel or circlesaw rotating.

The exponential of a pure imaginary number is the same thing as computing its sine and cosine, only written in a clever way. And no, this is not particularly CPU intensive, since chances are you were going to be computing the sine and cosine of your angle down the line anyway.

So my question is :
What is more CPU intensive, having the if, or having the huge float numbers ?

Why does it matter? Do you have a program that is not fast enough and your profiler is telling you that this piece of the code is responsible? I doubt it, since you only do it once a frame. Don't be obsessive about performance for pieces of code that are not in tight loops.

I would prefer keeping the angle in a small range around 0, because trigonometric functions will lose precision if you use huge angles.

Performance is irrelevant here.

What you should be worried about is loss of precision as the float value grows bigger. It will be fine for many many rotations but eventually it will become unprecise.

If you expect the float value to grow big enough to become unprecise, you NEED to do something about it or the math will break.

You prevent such things from happening by wrapping the float to 0-360 range, which you can do using the modulus operator (% for integers, fmod for floats), or by using a loop like Vortez showed (fmod will likely be more efficient since i believe its just a couple of simple arithmetic operations, faster than a loop with branches and whatnot)

o3o

Thanks Waterlimon and Alvaro about the presision, i did not notice that yet, to be honest i have no clue whats the underlaying idea about float, i was just asking to be sure.

With this information i now know i need the "if", the "if" is faster then any function like fmod i,m sure.

Maybe you all dont worry much about CPU intensivity as i do, i like many things in screen, not just 1 circlesaw, maybe you all have a i7 instead of a celeron ?

By example : your better off with a "if" instead of a "min()" or "max()" in terms of CPU usage, i avoid everything to be honest.

greetings and thanks again

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

With this information i now know i need the "if", the "if" is faster then any function like fmod i,m sure.

It's probably the other way around.

Modern CPUs are very complex to guess "what's faster" without context or actual profiling; but an 'if' requires a branch, and branch can involve pipeline stalls and cache misses (and if you're not targeting x86/x64 PCs, it also involves an LHS - Load-Hit-Store which is incredibly expensive).

fmod uses only math to do the same thing, and as such, can easily be pipelined (thus will run fast on most architectures).

Because the performance of the 'if' variant highly depends on branch predictors, its performance can't be evaluated without context (which means knowing the state of the branch predictor).

This topic is closed to new replies.

Advertisement