Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


float unlimited increasing rotation or use a if


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
53 replies to this topic

#1 the incredible smoker   Members   -  Reputation: 375

Like
1Likes
Like

Posted 29 December 2013 - 08:27 AM

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


Edited by the incredible smoker, 29 December 2013 - 08:27 AM.

S T O P   C R I M E !

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


Sponsor:

#2 Vortez   Crossbones+   -  Reputation: 2704

Like
2Likes
Like

Posted 29 December 2013 - 08:41 AM

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.


Edited by Vortez, 29 December 2013 - 08:47 AM.


#3 Waterlimon   Crossbones+   -  Reputation: 2599

Like
1Likes
Like

Posted 29 December 2013 - 09:25 AM

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


o3o


#4 the incredible smoker   Members   -  Reputation: 375

Like
1Likes
Like

Posted 29 December 2013 - 09:41 AM

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


#5 Álvaro   Crossbones+   -  Reputation: 13652

Like
4Likes
Like

Posted 29 December 2013 - 09:55 AM

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);

Edited by Álvaro, 29 December 2013 - 09:57 AM.


#6 the incredible smoker   Members   -  Reputation: 375

Like
0Likes
Like

Posted 29 December 2013 - 10:10 AM

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 ?


Edited by the incredible smoker, 29 December 2013 - 10:10 AM.

S T O P   C R I M E !

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


#7 Waterlimon   Crossbones+   -  Reputation: 2599

Like
8Likes
Like

Posted 29 December 2013 - 10:26 AM

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


#8 Álvaro   Crossbones+   -  Reputation: 13652

Like
6Likes
Like

Posted 29 December 2013 - 10:26 AM

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.

#9 the incredible smoker   Members   -  Reputation: 375

Like
-2Likes
Like

Posted 29 December 2013 - 10:43 AM

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


#10 Matias Goldberg   Crossbones+   -  Reputation: 3565

Like
3Likes
Like

Posted 29 December 2013 - 11:34 AM

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).



#11 the incredible smoker   Members   -  Reputation: 375

Like
0Likes
Like

Posted 29 December 2013 - 11:48 AM

Hello Matias, thanks for the reply.

I was looking for some info specific about what is called branching, it is still not clear to me :

 

if i use only the "if", and not the brackets after, is it still branching ?

and what if i only use the brackets like this, without the if :

 

{

// code here

}

 

does that also count as branching ?

 

greetings


S T O P   C R I M E !

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


#12 Waterlimon   Crossbones+   -  Reputation: 2599

Like
2Likes
Like

Posted 29 December 2013 - 12:14 PM

Branching is when the code executed next is chosen based on a condition. This includes of course if statements but also loops, since they need to decide whether to run the loop body one more time or stop looping based on the condition.

 

Also, things being functions/macros does not make them slow, because any modern compiler will be able to inline it if the function itself is simple. Eg. with the fmod, which is a couple of arithmetic operations, it is very likely that the same machine code is produced when you write the math inline yourself or use the function.


o3o


#13 jbadams   Senior Staff   -  Reputation: 19042

Like
7Likes
Like

Posted 30 December 2013 - 05:29 AM

Warning: the following may come across as a little harsh.  I don't mean to offend, but I think you might benefit from this advice (some of which has been offered in the posts above).

 


Maybe you all dont worry much about CPU intensivity as i do

You're worrying about it much more than you should, and unless you're using a profiler to measure alternatives there's a good chance you're just wasting your time or even actually making things slower/less efficient with your attempts to optimise.

 

Modern compilers are very complicated and able to do a lot of very clever optimisations on your code; very very talented programmers have put years of work into making them do this very effectively.  If one way of writing code is obviously inferior to another it's likely your compiler will make the change for you.  It takes a lot of experience to out-think your compiler and achieve better performance.

 

 

You should instead be more focused on writing code that is clear (i.e. easily read and understood) and correct (does what you want) and then only worrying about optimisation if you can actually demonstrate that your program isn't fast enough, at which point you would start to optimise the parts of your program your profiler shows to be the slowest rather than making guesses or trying to micro-optimise small things like you're worrying about in this topic.

 

By worrying about these low level details without actually measuring performance properly you're almost certainly simply making your code more harder to read, more complicated (and therefore more prone to bugs), and not actually gaining any performance over simply using the most obvious code and allowing your compiler to do it's work.  The very question you started this topic with is an obvious example -- it's likely that neither or your alternatives would perform better than the other once the optimising compiler has done it's job, but one version has a precision problem that will result in incorrect behaviour if not handled -- you're worrying needlessly about performance but hadn't noticed that one version of your program could be buggy.

 

 

Optimisation is absolutely an important and worthwhile topic, but you're simply not going about it the right way with your current approach.  Learn about proper optimisation and take advantage of the tools (profilers, optimising compilers, etc.) that are available to help you rather than "voo-doo/superstitious coding" where you avoid functions you think might be performance bottlenecks.

 

 

I hope that's helpful! smile.png



#14 Aardvajk   Crossbones+   -  Reputation: 6061

Like
4Likes
Like

Posted 30 December 2013 - 07:00 AM

if i use only the "if", and not the brackets after, is it still branching ?

and what if i only use the brackets like this, without the if :

 

{

// code here

}

 

does that also count as branching ?

 

greetings

 

If you are asking this, you are in absolutely no position to be worrying about whether branching is faster than a math operation or not. You need a really thorough understanding of what is going on under the hood of your compiler if you want micro-optimisations to be anything other than a total waste of time.



#15 the incredible smoker   Members   -  Reputation: 375

Like
-5Likes
Like

Posted 30 December 2013 - 10:26 AM

Let me tell like this : i have tested all this, get the time, repeat 1000 times, then get the time again.

Test showed me the simplest if was faster then functions, it was a while ago, i should test it again on my new pc maybe ?

Can a i7 be faster with sin() instead of a lookuptable? , and maybe a Celeron ( which is my current game development pc with onboard graphics ) cant ?

 

 

If you are asking this, you are in absolutely no position to be worrying about whether branching is faster than a math operation or not. You need a really thorough understanding of what is going on under the hood of your compiler if you want micro-optimisations to be anything other than a total waste of time.

 

 

 

If i worry about optimalization,i must be in some position, right ?

I have learned programming not on school, i also dont know how to use a debugger.

Is that a problem ?, i thought questions are never dumb, i skip learning everything that is not needed to get result, if i need something i can Always ask it.

 

But if you defending your own business, ofcourse you dont wanto tell the competition how to get your games optimized,

i,m telling you : games are not playable with functions like sin() and cos() and sqrtf() ( i still need to get some fast sqrtf function by the way ).

 

Note : i,m Always having 1000 bullets and explosions in screen, so maybe this does not count for your i7 pc with 2 bullet and 1 explosion ?

 

greetings


S T O P   C R I M E !

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


#16 SimonForsman   Crossbones+   -  Reputation: 6169

Like
2Likes
Like

Posted 30 December 2013 - 10:31 AM

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 ?

 

Rather than worry about which is fastest, worry about which will give you the correct result, (or atleast a correct enough result).

 

Trig functions on x86 are only accurate in the -PI to PI range (beyond that the results start to drift off and the error gets worse the further away from that range you get), a float also normally only has 32 bits of accuracy, making small increments to a huge floating point number will not give you the expected result, restricting the scale of your rotation value is necessary to ensure a sane behaviour, (you may not need to restrict it to the -PI to PI range, but you have to restrict it)

 

Languages such as Java will restrict arguments passed to trig functions for you (but does so with higher than native precision argument reduction which is pretty darn slow so with Java on x86 you absolutely should restrict it to the -PI to PI range).

 

If you are on an architecture without a FPU or with a fairly weak FPU you might benefit from ditching trig functions completely and instead use lookup tables(best to use integers for your rotations then, just remember that it will likely be slower than trig functions on a modern CPU due to cache misses (reading from RAM is very slow) or fast approximation functions (depending on what precision you need), on newer x86 you can also use SSE to implement very fast high precision trig functions (using exponents or taylor series)


Edited by SimonForsman, 30 December 2013 - 10:53 AM.

I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#17 the incredible smoker   Members   -  Reputation: 375

Like
0Likes
Like

Posted 30 December 2013 - 10:40 AM

Thanks Simon, valuable information.

 

@ jbadams : Is Microsoft Visual Studio Professional 2005 considered a modern compiler ? thanks.


Edited by the incredible smoker, 30 December 2013 - 10:45 AM.

S T O P   C R I M E !

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


#18 the incredible smoker   Members   -  Reputation: 375

Like
0Likes
Like

Posted 30 December 2013 - 10:51 AM

 

You should instead be more focused on writing code that is clear (i.e. easily read and understood) and correct (does what you want) and then only worrying about optimisation if you can actually demonstrate that your program isn't fast enough, at which point you would start to optimise the parts of your program your profiler shows to be the slowest rather than making guesses or trying to micro-optimise small things like you're worrying about in this topic.

 

By worrying about these low level details without actually measuring performance properly you're almost certainly simply making your code more harder to read, more complicated (and therefore more prone to bugs), and not actually gaining any performance over simply using the most obvious code and allowing your compiler to do it's work.  The very question you started this topic with is an obvious example -- it's likely that neither or your alternatives would perform better than the other once the optimising compiler has done it's job, but one version has a precision problem that will result in incorrect behaviour if not handled -- you're worrying needlessly about performance but hadn't noticed that one version of your program could be buggy.

 

 

Hi, i also have comments above the code, wich is the slow readable code,

ofcourse i know the importance of readable code, especially with a project this big, i dont know the line count, alot of files for sure,

more then fits the screen!


Edited by the incredible smoker, 30 December 2013 - 10:52 AM.

S T O P   C R I M E !

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


#19 Madhed   Crossbones+   -  Reputation: 3075

Like
3Likes
Like

Posted 30 December 2013 - 11:10 AM


Can a i7 be faster with sin() instead of a lookuptable? , and maybe a Celeron ( which is my current game development pc with onboard graphics ) cant ?

 

Lookup tables are so 1990's. Think of the cache. Processors have become lightning fast since then while ram speed has not.

Also the line "i,m telling you : games are not playable with functions like sin() and cos() and sqrtf() ( i still need to get some fast sqrtf function by the way )." had me a retro-chuckling.



#20 the incredible smoker   Members   -  Reputation: 375

Like
0Likes
Like

Posted 30 December 2013 - 11:28 AM

Ok, i will make a test, and test it on my Celeron and a i7, let see, interesting.


S T O P   C R I M E !

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





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS