GP2X Fixed Math Divide


cxzuk

Still Fresh
Joined
Aug 4, 2006
Messages
34
Hi all,

Been looking into the squidgeSnes code again, and noticed that the ticks stuff is constaint, or could be.

Fixed Point Divide Function
Code:
#define div(a,b) (int) ( ((((2^32)+b-1) / b) * (a)) / (2^32) )

Add to the minlib

Code:
//predefined.. so no math done here =)
#define ticks_per_second (7372800 / 1000)
#define ticks_math (((2^32)+ticks_per_second-1) / ticks_per_second)
#define ticks_passed(a) (int) ( (ticks_math * (a)) / (2^32) )

...

unsigned long gp2x_timer_read(void) {
  return ticks_passed(gp2x_memregl[0x0A00>>2]);
}

The accuracy is sacrifisted, but should be MUCH quicker =) Could someone give it ago and let me know how it goes?

Mike
 
It's usually good practice to put ( ) around the contents of a #define when it's got operations in it, otherwise when the preprocessor does the substitution, order of operations can do things you might not expect.
 
BradN posted on Aug 17 2006 at 09:45 PM said:
It's usually good practice to put ( ) around the contents of a #define when it's got operations in it, otherwise when the preprocessor does the substitution, order of operations can do things you might not expect.

Noted and edited
 
Last edited by a moderator:
gfoot posted on Aug 17 2006 at 11:26 PM said:
Do you really mean 2^32? 2^32 is 34...

Yep, 34. Is correct. Its to do with the data size.
 
Last edited by a moderator:
You've specified the whole thing as integer maths, so it just drops out - ticks_per_second is 7372, ticks_math is just 1, and so ticks_passed just divides by 34. Your defines end up semantically identical to:

Code:
#define ticks_passed(a) (int)((a) / 34)

which probably isn't what you intended. Maybe it's good enough for whatever your doing, but I get the feeling you might have overlooked something.
 
Define doesn't do what you think it does. The define'd code is just textually replaced where it is used before it is compiled. The -E option to gcc lets you see this.

Code:
andrew@andrew ~/Desktop $ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "test.c"

unsigned long gp2x_timer_read(void) {
  return (int) ( ((((2^32)+(7372800 / 1000)-1) / (7372800 / 1000)) * (gp2x_memregl[0x0A00>>2])) / (2^32) );
}

This is the code that is actually compiled - and it's really not much different to what you started with. Now GCC is a pretty good compiler, and it won't make the compiler do 7372800 / 1000 every time that is called. It will automatically calculate it at compile time, as it will with most of that expression.

You're really wasting your time with small stuff like this. As Donald Knuth said 'Premature optimisation is the root of all evil'. 95% of time is spent in 5% of the code, find that 5% then start work on optimising it.

Andrew
 
Back
Top