Sign in to follow this  
the incredible smoker

float unlimited increasing rotation or use a if

Recommended Posts

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

Share this post


Link to post
Share on other sites
Vortez    2714

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
alvaro    21266
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Matias Goldberg    9581

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Waterlimon    4398

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.

Share this post


Link to post
Share on other sites
Aardvajk    13207

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
SimonForsman    7642

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

Share this post


Link to post
Share on other sites

 

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

Share this post


Link to post
Share on other sites
Madhed    4095


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.

Share this post


Link to post
Share on other sites
cr88192    1570

 


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.

 

 

 

actually, IME, lookup tables *can* be pretty fast, provided they are all kept small enough to mostly fit in the L1 or (at least) L2 cache.

 

for example, a 256-entry table of 16-bit items: probably pretty fast.

OTOH, a 16k/32k/64k entry table of 32 or 64 bit items... errm... not so fast.

 

 

as for sin/cos/sqrt/...

probably not worth worrying about, unless there is good reason.

 

the performance issues with these, however, are not so much with the CPU as with how certain compilers handle the C library math functions.

but, in most cases, this should not matter (yes, including in the game logic and renderer).

 

I would not personally recommend sin or cos tables as an attempt at a "general purpose" solution, as this is unlikely to gain much (and if done naively will most likely be slower, more so if int<->float conversions and similar are involved).

 

 

for special-purpose use cases, they can make sense, but generally in the same sort of contexts where one will not typically be using floats either.

Share this post


Link to post
Share on other sites
Pink Horror    2459

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

 

If you have to ask questions like this, you're not really ready to do any low-level optimizations.

 

Also, going branchless isn't always a win. I've worked on optimization for some platforms where I actually got speed improvements by changing from heavily-optimized branchless floating-point math into the most basic, beginner-friendly if/else code possible. The previous optimizations had turned out to be very platform specific, and on some slower, simpler processors, branching wasn't relatively as bad as caching the extra instructions and performing redundant math.

 

Of course I only even tried this because the code I modified had showed up in a profile as something I should look at. Now, there's usually some platform-specific thing you can do to speed up your math, but I always prefer to start from the simplest possible reference implementation, and that implementation should be kept around as a compile option. You can also use a reference implementation to test whatever faster math you create.

Share this post


Link to post
Share on other sites
jbadams    25713

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 ?

Meaningless benchmarks will get you meaningless results.

You can't just test if statements vs. function calls and then apply those results everywhere in your code; you need to test each particular if statement against it's equivalent function, as sometimes one will be better, but in other cases that won't be true.

You also need to do your tests in release mode with optimization enabled, in which case the compiler may inline your function call or even leave code out entirely if it detects that it isn't needed or used. You need to test real code samples, not artificial things like functions vs. if.

1,000 items on screen isn't a big number, you should stop touting it like you have some crazy unusual performance needs.

VS Express 2005 is almost 10 years old, it's probably time to update. That being said, it's still smart enough to optimize many of the situations being discussed.

(Posted from mobile.)

Share this post


Link to post
Share on other sites

I have this software Original complete package, so i have to use this.

I dont think i can use the newest version with my keycode.

 

My lookuptables are usually 16-bit 512 or max 1024 sometimes, i dont know if this is a issue.

And i will do for every function a test, not test just 1 function and say its faster or slower, ofcourse.

btw : I dont aim for i7 PCs, i like my game playable for everyone, also those without the best system,

i still like old games to, if i reach to something like a Dreamcast game i will be happy enough,

i bet there are enough people without a expensive game pc.

 

+ this topic costs me lots of points,  time to play screenshot showdown before reaching zero ( will i be banned then lol ? ).

Anyways : Happy newyear all!

Share this post


Link to post
Share on other sites
Vortez    2714

The reason you got downvoted is because you worrie too much about meaningless micro-optimization. Those kind of optimization might had their use in the 80's, maybe even 90's, to a much lesser extend, but are all but useless nowaday. Your game wont run slower because you choose to use an if or a math function, i can garranty you.

 


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

 

Using a debugger is not hard, and as i always says, it's the programmer's best friend. I couldn't do much without a debugger to be honest, all i would do it guess what's wrong, until i ragequit and punch my computer smile.png. Seriously tho, this is really something you should learn to use, fast.

Edited by Vortez

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this