chili-epfl / chilitags

Robust Fiducial Markers for Augmented Reality And Robotics
http://chili.epfl.ch/software
123 stars 57 forks source link

Use floats instead of double when possible #57

Closed severin-lemaignan closed 9 years ago

severin-lemaignan commented 9 years ago

After playing a bit with the compile flags to get the best possible performances on Android, it appears that floats are much nicer to ARM Neon instructions than double.

It would be useful to replace all doubles by floats (including literals! 1.0 is a double while 1.0f is a float) where possible.

For the record: Based on https://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/ARM-Options.html#ARM-Options and http://community.arm.com/groups/tools/blog/2013/04/15/arm-cortex-a-processors-and-gcc-command-lines, the best flag combination I come up with is:

-O3 -mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -ffast-math

Also, neon vectorization only works on single-precision floats. It may make sense to check that we use float instead of double (which include: every float literal should be 1.0f instead of 1.0 !)...

qbonnard commented 9 years ago

or maybe a

class Chilitags {
#ifdef NEON
typedef float Real
#else
typedef double Real
#endif
...
};

And then change all the doubles to Chilitags::Real in the code (yay). Maybe opencv has already something like that ?

severin-lemaignan commented 9 years ago

I guess my issue was: do we really need doubles? (like... double gain...!) But nice joke anyway :-P

qbonnard commented 9 years ago

Thanks, your "float all the double" joke isn't bad either ;) Some double are here because OpenCV expects them anyway, then they got propagated everywhere. The answer to your question is in the missing benchmark, the precision one. For coordinates, I suppose that we don't need more than floats, but for angles, I don't know the impact.

Have you already replace doubles by float in chilitags ? Is there a change of performance on the desktop version ?

ayberkozgur commented 9 years ago

Qt's way of handling this is to define a qreal type that is 32 bits on ARM and 64 bits on x86, seems like the cleanest way to me.

Edit: I realized separating 32 bit and 64 bit literals is a pointless effort, most of the time we would just use things like 1.5f that has low precision. So it's best if we float all the double literals.

qbonnard commented 9 years ago

Implemented in #67