gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Floating-point math from within interrupt?

#165547 - biolizard89 - Fri Dec 26, 2008 10:43 pm

I'm working on an Xport project which needs to process some data within interrupt code (the Xport triggers a cart interrupt when new data arrives, and it needs to be processed immediately). The data processing code has a few floating-point operations. Unfortunately, very weird things happen when the code runs (a variable which is supposed to count up to about 100, one step per interrupt, instead immediately stays constant at a value a bit above 1000). I found that removing the float code causes it to work again.

Code:

// The GetAnalog function returns a short.

// This line causes a problem.
ir_track_ranges[ir_track_index] = (short)(pow(GetAnalog(ir_track_ir_port)/16.0, -1.078867)*21417.2055);

// Replacing the above with this line fixes the problem.
ir_track_ranges[ir_track_index] = GetAnalog(ir_track_ir_port);


The float code works perfectly when I call it outside of an interrupt. I've tried using both the Xport cart interrupt as well as the VBlank interrupt, same results, both of them have the problem.

I'm on the Xport version of DevKitAdvance, and since I'm using the Xport, I cannot upgrade to DevKitARM.

Does anyone know if there are problems with doing floating-point math from within interrupt code, particularly with old versions of DevKitAdvance? Any ideas on how I could fix this?

Thanks.

#165548 - Dwedit - Fri Dec 26, 2008 11:20 pm

Lots of possible paths to take here.
Does the interrupt use the IRQ stack, or the User stack? Is a stack getting smashed?
Is the floating point code slow enough that it triggers a nested interrupt?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#165550 - Miked0801 - Sat Dec 27, 2008 7:39 am

My initial thought is your fp code is so slow that it is nesting interrupts. Any chance of switiching it over to fixed point code?

#165564 - biolizard89 - Sat Dec 27, 2008 8:59 pm

Miked0801 wrote:
My initial thought is your fp code is so slow that it is nesting interrupts. Any chance of switiching it over to fixed point code?

Hmm, so I did a benchmark of the code and found that the floating-point algorithm took about 17.1ms to execute. Since the cart interrupt gets triggered every 5ms, it looks like you are correct, this would probably be the problem. I implemented a new version which uses a lookup table instead of the float algorithm, and it benchmarked at about 12 microseconds to execute -- I'm amazed at how much faster this is. So I tried using the table algorithm instead of the float algorithm in the interrupt routine, and now it works!

Thanks for the help!

#165950 - elyk1212 - Wed Jan 14, 2009 6:45 am

Hey, I am curious what kind of tool/method did you use to benchmark the GBA code. This info would be very useful to me.

Thanks!

#165953 - biolizard89 - Wed Jan 14, 2009 8:50 am

elyk1212 wrote:
Hey, I am curious what kind of tool/method did you use to benchmark the GBA code. This info would be very useful to me.

Thanks!

My Xport logic has a microsecond timer on it, so I just executed the function 10000 times in a for loop, and polled the microsecond timer before and after the loop. The difference, divided by 10000, was the average execution time of the function. Not exactly the most accurate benchmark imaginable, but it gave me all the information I needed.

If your GBA code isn't using some of your GBA hardware timers, you could probably rig up something similar using those. The Xport worked great for me though.

#165968 - Miked0801 - Wed Jan 14, 2009 7:06 pm

The VCount register can also be used to messure your code in lines. I forget the translation from lines to cycles or MSeconds, but it' still a valid tool as long as no other interrupts hit you in between readings.