Thursday, December 20, 2012

Floating point operations: hardware vs software


This is a (maybe incomplete) list of floating point operations in GCC:
__udivsi3
_vfprintf_r
__eqdf2
__nedf2
__umoddi3
__udivdi3
__ltdf2
__eqdf2
__nedf2
__negdf2
__udivsi3
__eqdf2
__subdf3
__muldf3
__adddf3
__floatsidf
__muldf3
__adddf3
__fixdfsi
__ltdf2
__gtdf2
__divdf3
__muldf3
__divdf3
__ltdf2
__muldf3
__floatsidf
__muldf3
__adddf3
__subdf3
__gtdf2
__negdf2
__gtdf2
__muldf3
__gedf2
__divdf3

Depending on gcc/g++ compilation flag (e.g. -msoft-float), the linker will link these instructions to either calls to hardware FPU (x87 on x86 machines), or use user-defined libraries which implement the above-mentioned functions. 


The only difference between hw versus sw FP operations should be speed, because in sw the same algorithms are applied as in hw.


An example of fp div operation (from Apple oss clang implementation): http://www.opensource.apple.com/source/clang/clang-163.7.1/src/projects/compiler-rt/lib/divdf3.c


In reality, some FPUs have certain features like not making the rounding until the operand is written to memory; this causes some rounding improvements over sw implementations.

However, for precise FP operations (e.g. like the ones used in financial applications), libraries exist which reduce even more the rounding errors: e.g. Java's BigDecimal, GMP (http://gmplib.org/), etc.

No comments: