Patch to improve irrXML's fast_atof
Posted: Thu Feb 03, 2011 9:32 pm
Hi! I'm the Fedora maintainer for the Irrlicht Engine (and IrrXML). Recently, another Fedora contributor wanted to package up and include the Open Asset Import Library, aka assimp (http://assimp.sourceforge.net/). During the review process, it was discovered that assimp was using a modified copy of IrrXML, which is almost never permitted in Fedora. Further investigation revealed that the only changes were to improve fast_atof.
I know that there is a comment in the IrrXML code that says:
However, that code doesn't run on Linux, only Windows. So I fixed it to run on Linux. A copy of the updated regression test code with Linux support can be found here:
https://bugzilla.redhat.com/attachment.cgi?id=461140
Once I'd fixed up the test code (and built/installed a local 1.7.2 package), I
compiled it like this:
gcc -m64 -I/usr/include/irrlicht fast_atof.cpp -o fast_atof-172 -lIrrlicht
-lstdc++ -lm
Without any changes to IrrXML, this is a sample result on Fedora 14 x86_64:
This means that the test is showing that the atof() in Fedora 14 glibc is faster than the fast_atof function, but what I really wanted to see was what difference (if any) the assimp changes to fast_atof had.
So, I applied the assimp changes to IrrXML and recompiled Irrlicht. A copy of the patch is here: http://spot.fedorapeople.org/irrlicht-1 ... ents.patch
One of the nice things about this patch is that there is a tunable variable that can be adjusted at compile time, to specify the number of relevant decimals for floating-point parsing. Initially assimp had AI_FAST_ATOF_RELAVANT_DECIMALS set to 6, but when I tested that, I got a lot of results like this:
So, I bumped it up to 15, and did three runs. Here are the final results from the three runs:
When you average those results, you get:
The fast_atof time with the assimp patch and AI_FAST_ATOF_RELAVANT_DECIMALS 15 is approx 1.6x faster than glibc atof.
Then, I tried setting the field to 10, and did three runs again:
The fast_atof time with the assimp patch and AI_FAST_ATOF_RELAVANT_DECIMALS 10 is approx 1.4x faster than glibc atof. Approx 1.7x faster than stock 1.7.2 fast_atof.
*****
Phew! If you are still reading, thanks. We would like for this patch to be considered for IrrXML (and Irrlicht), because it would mean that assimp could use the system copies of IrrXML on Fedora instead of bundling its own copy.
In case you missed it before, the patch (against 1.7.2) is here:
http://spot.fedorapeople.org/irrlicht-1 ... ents.patch
It only touches include/fast_atof.h and include/irrTypes.h (to fix up and conditionalize some additional types for Windows and Linux).[/code]
I know that there is a comment in the IrrXML code that says:
Code: Select all
// Please run this regression test when making any modifications to this function:
// https://sourceforge.net/tracker/download.php?group_id=74339&atid=540676&file_id=298968&aid=1865300
https://bugzilla.redhat.com/attachment.cgi?id=461140
Once I'd fixed up the test code (and built/installed a local 1.7.2 package), I
compiled it like this:
gcc -m64 -I/usr/include/irrlicht fast_atof.cpp -o fast_atof-172 -lIrrlicht
-lstdc++ -lm
Without any changes to IrrXML, this is a sample result on Fedora 14 x86_64:
Code: Select all
String '340282346638528859811704183484516925440.000000'
New fast 340282346638528859811704183484516925440.0000000000000000000000000000000000000000
Old fast 0.0000000000000000000000000000000000000000
atof 340282346638528859811704183484516925440.0000000000000000000000000000000000000000
String '3.402823466e+38F'
New fast 340282326356119256160033759537265639424.0000000000000000000000000000000000000000
Old fast 3.4028234481811523437500000000000000000000
atof 340282346638528859811704183484516925440.0000000000000000000000000000000000000000
String '3402823466e+29F'
New fast 340282346638528859811704183484516925440.0000000000000000000000000000000000000000
Old fast 3402823424.0000000000000000000000000000000000000000
atof 340282346638528859811704183484516925440.0000000000000000000000000000000000000000
String '-340282346638528859811704183484516925440.000000'
New fast -340282346638528859811704183484516925440.0000000000000000000000000000000000000000
Old fast -0.0000000000000000000000000000000000000000
atof -340282346638528859811704183484516925440.0000000000000000000000000000000000000000
String '-3.402823466e+38F'
New fast -340282326356119256160033759537265639424.0000000000000000000000000000000000000000
Old fast -3.4028234481811523437500000000000000000000
atof -340282346638528859811704183484516925440.0000000000000000000000000000000000000000
String '-3402823466e+29F'
New fast -340282346638528859811704183484516925440.0000000000000000000000000000000000000000
Old fast -3402823424.0000000000000000000000000000000000000000
atof -340282346638528859811704183484516925440.0000000000000000000000000000000000000000
String '34028234663852885981170418348451692544.000000'
New fast 34028234663852885981170418348451692544.0000000000000000000000000000000000000000
Old fast 0.0000000000000000000000000000000000000000
atof 34028234663852885981170418348451692544.0000000000000000000000000000000000000000
String '3.402823466e+37F'
New fast 34028234663852885981170418348451692544.0000000000000000000000000000000000000000
Old fast 3.4028234481811523437500000000000000000000
atof 34028234663852885981170418348451692544.0000000000000000000000000000000000000000
String '3402823466e+28F'
New fast 34028232128551685524711615355045281792.0000000000000000000000000000000000000000
Old fast 3402823424.0000000000000000000000000000000000000000
atof 34028234663852885981170418348451692544.0000000000000000000000000000000000000000
String '-34028234663852885981170418348451692544.000000'
New fast -34028234663852885981170418348451692544.0000000000000000000000000000000000000000
Old fast -0.0000000000000000000000000000000000000000
atof -34028234663852885981170418348451692544.0000000000000000000000000000000000000000
String '-3.402823466e+37F'
New fast -34028234663852885981170418348451692544.0000000000000000000000000000000000000000
Old fast -3.4028234481811523437500000000000000000000
atof -34028234663852885981170418348451692544.0000000000000000000000000000000000000000
String '-3402823466e+28F'
New fast -34028232128551685524711615355045281792.0000000000000000000000000000000000000000
Old fast -3402823424.0000000000000000000000000000000000000000
atof -34028234663852885981170418348451692544.0000000000000000000000000000000000000000
String '.00234567'
New fast 0.0023456700146198272705078125000000000000
Old fast 0.0023456700146198272705078125000000000000
atof 0.0023456700146198272705078125000000000000
String '-.00234567'
New fast -0.0023456700146198272705078125000000000000
Old fast -0.0023456700146198272705078125000000000000
atof -0.0023456700146198272705078125000000000000
String '0.00234567'
New fast 0.0023456700146198272705078125000000000000
Old fast 0.0023456700146198272705078125000000000000
atof 0.0023456700146198272705078125000000000000
String '-0.00234567'
New fast -0.0023456700146198272705078125000000000000
Old fast -0.0023456700146198272705078125000000000000
atof -0.0023456700146198272705078125000000000000
String '1.175494351e-38F'
New fast 0.0000000000000000000000000000000000000118
Old fast 0.0000000000000000000000000000000000000118
atof 0.0000000000000000000000000000000000000118
String '1175494351e-47F'
New fast 0.0000000000000000000000000000000000000000
Old fast 1175494400.0000000000000000000000000000000000000000
atof 0.0000000000000000000000000000000000000118
String '1.175494351e-37F'
New fast 0.0000000000000000000000000000000000001175
Old fast 0.0000000000000000000000000000000000001175
atof 0.0000000000000000000000000000000000001175
String '1.175494351e-36F'
New fast 0.0000000000000000000000000000000000011755
Old fast 0.0000000000000000000000000000000000011755
atof 0.0000000000000000000000000000000000011755
String '-1.175494351e-36F'
New fast -0.0000000000000000000000000000000000011755
Old fast -0.0000000000000000000000000000000000011755
atof -0.0000000000000000000000000000000000011755
String '123456.789'
New fast 123456.7890625000000000000000000000000000000000
Old fast 123456.7890625000000000000000000000000000000000
atof 123456.7890625000000000000000000000000000000000
String '-123456.789'
New fast -123456.7890625000000000000000000000000000000000
Old fast -123456.7890625000000000000000000000000000000000
atof -123456.7890625000000000000000000000000000000000
String '0000123456.789'
New fast 123456.7890625000000000000000000000000000000000
Old fast 123456.7890625000000000000000000000000000000000
atof 123456.7890625000000000000000000000000000000000
String '-0000123456.789'
New fast -123456.7890625000000000000000000000000000000000
Old fast -123456.7890625000000000000000000000000000000000
atof -123456.7890625000000000000000000000000000000000
atof time = 401
fast_atof Time = 543
old fast_atof time = 439
The fast method isn't at least three times as fast as atof()
So, I applied the assimp changes to IrrXML and recompiled Irrlicht. A copy of the patch is here: http://spot.fedorapeople.org/irrlicht-1 ... ents.patch
One of the nice things about this patch is that there is a tunable variable that can be adjusted at compile time, to specify the number of relevant decimals for floating-point parsing. Initially assimp had AI_FAST_ATOF_RELAVANT_DECIMALS set to 6, but when I tested that, I got a lot of results like this:
Code: Select all
String '-.00234567'
New fast -0.0023449999280273914337158203125000000000
Old fast -0.0023456700146198272705078125000000000000
atof -0.0023456700146198272705078125000000000000
*** ERROR - less accurate than old method ***
Code: Select all
Run 1:
atof time = 478
fast_atof Time = 268
old fast_atof time = 486
The fast method isn't at least three times as fast as atof()
Run 2:
atof time = 446
fast_atof Time = 267
old fast_atof time = 461
The fast method isn't at least three times as fast as atof()
Run 3:
atof time = 399
fast_atof Time = 295
old fast_atof time = 462
The fast method isn't at least three times as fast as atof()
Code: Select all
Averaged:
atof time = 441
fast_atof Time = 276
old fast_atof time = 469
Then, I tried setting the field to 10, and did three runs again:
Code: Select all
atof time = 451
fast_atof Time = 273
old fast_atof time = 476
The fast method isn't at least three times as fast as atof()
atof time = 428
fast_atof Time = 310
old fast_atof time = 531
The fast method isn't at least three times as fast as atof()
atof time = 406
fast_atof Time = 309
old fast_atof time = 490
The fast method isn't at least three times as fast as atof()
Averaged:
atof time = 428.3
fast_atof Time = 297.3
old fast_atof time = 499
*****
Phew! If you are still reading, thanks. We would like for this patch to be considered for IrrXML (and Irrlicht), because it would mean that assimp could use the system copies of IrrXML on Fedora instead of bundling its own copy.
In case you missed it before, the patch (against 1.7.2) is here:
http://spot.fedorapeople.org/irrlicht-1 ... ents.patch
It only touches include/fast_atof.h and include/irrTypes.h (to fix up and conditionalize some additional types for Windows and Linux).[/code]