BattleCattle
Member
- Joined
- Oct 4, 2005
- Messages
- 59
So, I'm starting to work on a 3D Library I'm designing for the GP2X (yes, another 3D lib being worked on, this one designed for performance from the ground up hopefully), and am having a difficult time deciding what internal representation of numbers I should use (floating point, fixed point, etc), and had a couple of questions. Here's what I'm looking at:
Non-integer numbers are generally stored in the form n * 2^e. as I understand it, with floating point, the number of bits dedicated to n & e can change, that is, the precision of each of the values can change. With fixed point, a certain number of bits are set aside for n, and a certain number of bits are set aside for e. This gives rise to four possible implementations (that immediately come to mind at least)
#1: using the standard 'float' data type -
Pros:
* 32 bit representation (balanced between accuracy and memory usage)
* flexible and versatile - can represent a large range of numbers fairly accurately
* no need to write math functions/macros involving bit shifts, etc
Cons:
SLOW, due to no FPU on-chip
#2: using a standard fixed-point (a 32 bit integer split, part of the bits for n part for e)
Pros:
* significantly faster than floating-point
* tried & true method - many resources/guides
Cons:
* significantly more rounding errors and narrower range of numbers represented than floats
* need to write own math functions using bit-shifts (no big deal really)
* big loss of precision during multiplication, due to lack of 64-bit intermediate representation of numbers during calculations
#3: use an extended fixed-point, separating n from e into two separate integers
Pros:
* Large range of numbers able to be accurately represented
* less concern about loss of precision / bad results from multiplication than standard fixed point (still an issue though)
Cons:
* more complicated / slower custom math functions (cannot just bit-shift to swap bits between n and e)
* more memory usage
#4: use an integer-based representation of floating point (a long int for the actual value, and then a single byte integer to specify how many bits of that value represent e)
Pros:
* floating-point precision using integer math
Cons:
* complicated custom math functions (might be) slower than just using floats in the first place (imagine multiplying two such numbers with different numbers of bits for the mantissa)
* still has a large loss of precision when multiplying, due to lack of 64 bit intermediate representation
The complexity of the math functions of #4 make me think that I probably wouldn't save any clock cycles (if any), and the difficulty shifting bits between n and e as well as the increased memory usage seem to make #3 less than ideal.
On the other hand, the slow operations of #1 and the loss of precision of multiplications of #2 make me cautious.
Any opinions out there as to what internal representation would probably be best for a 3D library for our lovely GP2X here? Granted I could always encapsulate the functionality that I need in a class and test out each of the four implementations to test for performance & accuracy, but I'm hoping to at least start by getting a working version with what I think will be the best overall. Also, does anyone have any quantitative data on how MUCH slower floating-point operations take on the ARM architecture (assuming GCC 4 optimizations)?
Non-integer numbers are generally stored in the form n * 2^e. as I understand it, with floating point, the number of bits dedicated to n & e can change, that is, the precision of each of the values can change. With fixed point, a certain number of bits are set aside for n, and a certain number of bits are set aside for e. This gives rise to four possible implementations (that immediately come to mind at least)
#1: using the standard 'float' data type -
Pros:
* 32 bit representation (balanced between accuracy and memory usage)
* flexible and versatile - can represent a large range of numbers fairly accurately
* no need to write math functions/macros involving bit shifts, etc
Cons:
SLOW, due to no FPU on-chip
#2: using a standard fixed-point (a 32 bit integer split, part of the bits for n part for e)
Pros:
* significantly faster than floating-point
* tried & true method - many resources/guides
Cons:
* significantly more rounding errors and narrower range of numbers represented than floats
* need to write own math functions using bit-shifts (no big deal really)
* big loss of precision during multiplication, due to lack of 64-bit intermediate representation of numbers during calculations
#3: use an extended fixed-point, separating n from e into two separate integers
Pros:
* Large range of numbers able to be accurately represented
* less concern about loss of precision / bad results from multiplication than standard fixed point (still an issue though)
Cons:
* more complicated / slower custom math functions (cannot just bit-shift to swap bits between n and e)
* more memory usage
#4: use an integer-based representation of floating point (a long int for the actual value, and then a single byte integer to specify how many bits of that value represent e)
Pros:
* floating-point precision using integer math
Cons:
* complicated custom math functions (might be) slower than just using floats in the first place (imagine multiplying two such numbers with different numbers of bits for the mantissa)
* still has a large loss of precision when multiplying, due to lack of 64 bit intermediate representation
The complexity of the math functions of #4 make me think that I probably wouldn't save any clock cycles (if any), and the difficulty shifting bits between n and e as well as the increased memory usage seem to make #3 less than ideal.
On the other hand, the slow operations of #1 and the loss of precision of multiplications of #2 make me cautious.
Any opinions out there as to what internal representation would probably be best for a 3D library for our lovely GP2X here? Granted I could always encapsulate the functionality that I need in a class and test out each of the four implementations to test for performance & accuracy, but I'm hoping to at least start by getting a working version with what I think will be the best overall. Also, does anyone have any quantitative data on how MUCH slower floating-point operations take on the ARM architecture (assuming GCC 4 optimizations)?