Thursday, September 11, 2008

Performance: encapsulate floating point and built-in tolerance

When it comes to the floating point comparison with tolerance, two approaches come into my mind.
The first approach is to write inline functions and call them when compare floating point numbers. It is easy to understand and is widely used by numerous applications. Yes, it is really simple and I like it. The only concern is that I have to call these functions explicitly when compare two float or double variables, and I have to be aware of the code where it is necessary to compare with tolerance.
The second approach is to encapsulation floating point using a class. A float variable is the only member variable and I have to override lots of operators, assignment operator, relational and equality operators to control flow, arithmetic, unary, prefix and postfix operators. But how to implement the class is not a big deal, I'm worrying about the performance decrease which is introduced by using classes instead of pure machine data type.
Then I write the first to my open source library LibG, and made unit test for performance. The result looks good to me.
Testing Environment Hardware1: CPU: AMD Sempron 2600+ (1.6G Hz). Memory: 1G, DDR400
Hardware2: CPU: Intel Core2 6300 (1.86G Hz). Memory: 4G
Software: Windows XP Professional with SP2
Testing Method
Repeat 15million times of a set of operations. There are one additional assignment, one comparison and one pre-decrement to complete the loop. Run 10 times and get average time.
Source Code Open source portal of LibG: http://code.google.com/p/libg/
The class giFloat and giDouble: http://code.google.com/p/libg/source/browse/trunk/inc/gifloat.h
The testing code: http://code.google.com/p/libg/source/browse/trunk/test/libg_unit_test/test_gifloat.cpp
Testing Result 1. Arithmetic Operations: Operations Set: +, -, *, /, +=, -=, *=, /=
Testing Result (ms) float giFloat double giDouble
Hardware1 856.3 837.3 336.1 337.6
Performance +2.22% -0.45%
Hardware2 517.2 517.3 528.1 504.7
Performance -0.02% +4.43%
The performance of using class is very close to machine data type.
2. Relational and Equality Operations: Operations Set: ==, !=, >, >=, <, <=
Result float
(no tolerance)
float
(inline functions)
giFloat double
(no tolerance)
double
(inline functions)
giDouble
Hardware1 378.1 667.2 734.4 270.3 435.9 482.8
Performance -10.07% -9.71%
Hardware2 165.6 282.8 312.7 151.4 237.7 237.3
Performance -9.56% +0.12%
Comparing with using inline functions, the performance of using class decreased about 10%, it's acceptable to me. The data type double is the most frequently used type on geometry computation, the performance result on Intel Core2 CPU is exciting.

No comments:

Post a Comment