Page 1 of 1

Optimization question floating point

Posted: January 20th, 2019, 8:12 am
by sleepingburrito
I know the PS1 does not have native floating point on the CPU but I was making a game where not many things use it so I felt like it was an ok trade off to use it. I did come across one instance where its noticeable but its not a big deal if I can't fix it.

I have a knock back function and its basically like this, I omitted not necessary code:

Code: Select all

float angle, tmpYSub, tmpXSub;
tmpYSub = npc.x - knockback.x;
tmpYSub = npc.y - knockback.y;

if (sqrt(tmpYSub * tmpYSub + tmpXSub * tmpXSub) < knockback.range){
	angle = atan2(tmpYSub, tmpXSub);
	*npcHspeedInOut += knockback->intensity * cos(angle);
	*npcVspeedInOut += knockback->intensity * sin(angle);
}
I have commented out and tested each part of the code. I have found that atan2 is slowing it down a lot, It skips like 1-3 frames when I use it. I only use it for one frame when something uses knock back so its not too bad, and its only really bad in big explosions with lots of objects getting hit. I did google "fast atan2 in c" but what I found was slower than the one from the SDK or was X86 specific.

Im ok with replacing it with something that's much less accurate. Finding the distance is the next slowest part but "abs(tmpYSub) + abs(tmpXSub)" was a good trade off for me, so im mostly looking to replace atan2. Thanks for reading!

Re: Optimization question floating point

Posted: January 21st, 2019, 12:03 am
by Orion_
sqrt is slow too, since you only use it for a comparison, you can omit the squareroot by squaring knockback.range
if ((tmpYSub * tmpYSub + tmpXSub * tmpXSub) < (knockback.range * knockback.range))

I searched for fixed point atan2 on my harddrive and found this code:


I don't know where it's from, but maybe that can help you speed your code.
doing fixed point is easy, instead of "float" you declare an "int" value, and do some bit shifting.
for example:
float a = 1.2;
float b = 1.5;
float c = a*b;

fixed point equivalent:
int a = (int)(1.2 * 256.0);
int b = (int)(1.5 * 256.0);
int c = (a*b)>>8;

if you want to get the float value of C, you just divide by 256.0, or the integer part: >> 8

Re: Optimization question floating point

Posted: January 21st, 2019, 7:19 am
by Sblorgz
Take advantage of fixed point math (float operations are horribly slow) and use SquareRoot0 for magnitude and catan instead of atan2 for direction.

Re: Optimization question floating point

Posted: January 21st, 2019, 11:32 am
by LameGuy64
I don't recommend making extensive use of floating point math on the PS1 as FPU emulation is just very slow on the already slow R3000 so fixed point integer math is recommended.

Try using ratan2(), SquareRoot0(), csin() and ccos() and convert your arithmetic to fixed point integer math. Using 12-bit fractions (4096 = 1.0f) is recommended as most of the fixed point math functions in the GTE library use that format.

Re: Optimization question floating point

Posted: January 21st, 2019, 7:16 pm
by sleepingburrito
Thank you all.

Re: Optimization question floating point

Posted: February 5th, 2019, 11:41 pm
by Xavi92
libfixmath provides handy functions and types for fixed-point arithmetic on C and C++.

Re: Optimization question floating point

Posted: April 1st, 2019, 4:06 am
by Shadow
You could also use a pre-compiled or pre-calculated table so all the math is already processed to your application needs.