Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Speed Performance using either float or fixed

This thread is locked; no one can reply to it. rss feed Print
Speed Performance using either float or fixed
Kevin Epps
Member #5,856
May 2005
avatar

I know that there were some threads regarding this, but I just want clarification:

I have the following machines that I test on (all Windows so far):

P4 XP 2.8GHZ 256MB Nvidia Gfx card
Celeron 2000 1.1GHZ 4MB ATI GFX card
Celeron 2000 1.1GHZ 128MB ATI GFX card

All angle and position calculation uses floats.

On the P4, everything is fine. FPS 60 Runs smoothly.

On the other machines, runs slower, like 25 - 30 FPS. Was running at least 45 FPS until I changed all of the angle and position values to floats, which works well for me, a lot better than fixed. On slower machines under a P4, do I HAVE to use fixed to get a better performance?

ReyBrujo
Moderator
January 2001
avatar

It depends on the calculations, but in older processors fixed may be a good alternative.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Kevin Epps
Member #5,856
May 2005
avatar

ok.

So let's say I have the following code:

1float x;
2float x_vel;
3float speed;
4 
5....
6 
7if (x_vel > -speed)
8 x_vel-=0.1;
9 
10x += x_vel;
11 
12...
13 
14masked_blit(src, dest, 0, 0, fixtoi(ftofix(x)), fixtoi(ftofix(y)), src->w, src->h);

This is basically how I'm calculating the positioning. Is the the best way to impletment this?

Also, Let's say that I wanted something to move at speed = 5.5, how is declaring speed as a "fixed" type going to help me with that? Use (int)fixtof(speed)+0.5 or something?

ReyBrujo
Moderator
January 2001
avatar

I believe ftofix is a slow function, you should calculate everything using fixed points, or just determine your program needs a big processor to run. You would create a constant, like const fixed constant_speed = ftofix(5.5);, that way you would calculate it only once.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Steve Terry
Member #1,989
March 2002
avatar

Your example code isn't efficient, you are using floats, casting to fixed, then casting to int, that's slow no matter how you look at it.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Audric
Member #907
January 2001

Kevin Ebbs said:

masked_blit(src, dest, 0, 0, fixtoi(ftofix(x)), fixtoi(ftofix(y)), src->w, src->h);Is the the best way to implement this?

Why not simply :
masked_blit(src, dest, 0, 0, (int)x, (int)y, src->w, src->h);

Kevin Epps
Member #5,856
May 2005
avatar

Quote:

Why not simply :

masked_blit(src, dest, 0, 0, (int)x, (int)y, src->w, src->h);

Ooops! I put in code from my old code. Sorry about. Yeah that above masked_blit in the quote is actually what I use.

Jonny Cook
Member #4,055
November 2003

In the Allegro tests folder, there's a program called test.exe (at least for me). Check out "Time some stuff" in the Misc menu. As the name suggests, it times a bunch of stuff, including fixed point math and floating point math. Check it out on different computers. On my computer, (AthlonXP 2200), floating point arithmetic is faster than fixed pointer arithmetic, but the fixed point trig functions are much faster than the floating point ones. This probably is due to lookup tables.

What you could always do is store all the angles and position and everything else as floats, and when you need to do some speed critical trig stuff, just convert them to fixed point numbers.

The face of a child can say it all, especially the mouth part of the face.

Kevin Epps
Member #5,856
May 2005
avatar

[edit]
Oh yeah, thanks for the tip about the test exe's.
[/edit]

Well, that's pretty much what I do for the angle calcs.

y = length * fixtof(fixsin(ftofix(angle)));
x = length * fixtof(fixcos(ftofix(angle)));

But what about for movement calc's like using velocity to move a sprite?

if (x_vel < speed) 
  x_vel+=0.1;

x += x_vel;

Do i need to change any of these to fixed while doing this type of calc? Or is the pretty much the best I can do when it comes to this?

Carrus85
Member #2,633
August 2002
avatar

y = length * fixtof(fixsin(ftofix(angle)));
x = length * fixtof(fixcos(ftofix(angle)));

Hmm, call me naive or whathaveyou, but that seems, at best, to be a bad idea. You are converting float->fix, doing trig, then converting fix->float. float->fix and fix->float are slow operations (there is no native conversion operation for fixed point numbers, AFAIK).

I would be very surprised that, if on modern hardware, that is any faster than this:

y = length * sin(angle);
x = length * cos(angle);

Yes, I know fixed point trig utilizes lookup tables, but I doubt the speed gain from lookup tables is going to outweight the speed loss from fix-float or float-fix conversion.

Kevin Epps
Member #5,856
May 2005
avatar

Well,

I know that certain calls are don't really matter for modern machines, but a lot of people may not have modern machines and I know quite a few people that don't. So, I would like to make sure that my game can run on machines below P4 as well.

Kitty Cat
Member #2,815
October 2002
avatar

I have a 1.1GHz machine and use floating point just fine. The thing to keep in mind when using floats is to use floats. Don't go converting them to and from int or fixed or anything like that unless absolutely necessary. There may be a few things you can do to convert to int and be faster (eg. a sine lookup table for slower machines), but these will generally amount to a few FPS at most (and as a side effect, lose a few FPS for most newer machines).

If you need to convert to int/fixed alot (for say, Allegro functions) it may be better to use fixed. Fixed is also nice when doing bit-wise operations. Allegro's 3d math functions, though, have both fixed point and floating point variations.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Goalie Ca
Member #2,579
July 2002
avatar

Would someone remind me why people have been using fixed point anymore. i686 handles floats just fine. Newer CPU's handle them better than fine, they handle them damn fast!

-------------
Bah weep granah weep nini bong!

Kevin Epps
Member #5,856
May 2005
avatar

Well,

I just posted a demo of my game in the depot forum to see how it runs on the majority's computers. If everyone is able to run it at 60 FPS, then I'll just assume that mostly everyone has modern computers that can handle float and continue. If not, then I'll have to rewrite some code as fixed. Hopefully, it's not the latter.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

Would someone remind me why people have been using fixed point anymore.

Accuracy, for one. You'll always have 16 bits reserved for sub-integer precision. No more, no less. Makes it easier for checking and comparing. Plus it's rather fast for converting to int, so it's very useful for tight speed sensitive loops. And, you can do this:

// Set range 0..256 (inclusive-exclusive)
fixedNum &= 0xFFFFFF;

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Audric
Member #907
January 2001

I posted the performance I get in the other thread.
From what I saw, there's like 20 objects moving onscreen, not rotated, and moving in straight lines... The screen however seems to be in 800x600 or something, hi color, drawing rather big things (like earth).
Your logic step should take like 1% CPU on almost anybody's computer. even on a 386 sx25, there's no way it can reach 10% - except if you've coded in some super-inefficient way : but then, it will still be only 10%

Switching from ints to fix to floats could make this time (1% to 10%) double or halve, and nothing more.

IMO, you should
1) profile. My guess can be wrong
2) focus on optimizing what takes 90% time. not what takes 10% time.

edit:

Goalie Ca said:

Would someone remind me why people have been using fixed point anymore

Link by ReyBrujo in another thread: Problems with floating-points

Kevin Epps
Member #5,856
May 2005
avatar

Hey Audric

I had answered your question on the depot thread:

this is my game loop code:

1void example_game_function()
2{
3 bool run = true;
4 bool draw=false;
5 while (run)
6 {
7 if(speed_counter > 0)
8 {
9 do
10 {
11 
12 //put movement, any logic code here
13
14 speed_counter--;
15 curSkip++;
16 if (curSkip >= maxSkip) {
17 speed_counter = 0;
18 break;
19 }
20 } while(speed_counter > 0);
21 draw=true;
22
23 }
24 
25 if(draw) {
26 draw=false;
27 BeginDrawing();
28 // draw, pard'ner!!
29 clear(buffer);
30 
31 //put drawing code ONLY here
32 
33 EndDrawing();
34 xframe_count++;
35 }
36
37 } //while
38}
39// using triple buffering

Question about Profiling, though. In the results where should I be looking to determine speed of drawing and logic, if I can do that, that is.

Steve++
Member #1,816
January 2002

Quote:

Yes, I know fixed point trig utilizes lookup tables, but I doubt the speed gain from lookup tables is going to outweight the speed loss from fix-float or float-fix conversion.

There's also performance loss from having to cache those lookup tables.

All CPUs from about 486 DX2/66 have an integrated floating point processor (I think it may have become part of the core at some stage). Processing floats isn't (much) more expensive than processing ints.

I would agree that the advantage of fixed is that you get guaranteed accuracy with the number itself, but when you start dealing with increasingly smaller numbers, things start getting ugly. The only time floating point accuracy is threatened is when huge numbers meet tiny numbers.

If you're using Direct3D or OpenGL, you'll need to convert to float anyway, so have a think about that.

Audric
Member #907
January 2001

Go to: