Hi! I & my friend has made some investgations about O'Caml flotaing-point code quality. We discovered some strange code examples(all assembler code is for IA32 architecture): -------------------------------------------------------------------------- 1. "let _ = f a in" and "ignore (f a);" generates different code. for example: let _ = ignore (sin 1.0); () produces the following: 1 Float2_entry: 2 subl $8, %esp 3 .L100: 4 fld1 5 subl $8, %esp 6 fstpl 0(%esp) 7 call sin 8 addl $8, %esp 9 fstpl 0(%esp) ;-----------------------! floating value boxed before discarding 10 call caml_alloc2 12 .L101: 13 leal 4(%eax), %eax 14 movl $2301, -4(%eax) 15 fldl 0(%esp) 16 fstpl (%eax) ;----------------------------------------------------------------- 17 movl $1, %eax 18 addl $8, %esp 19 ret let _ = let _ = sin 1.0 in () produces the following (much more better) code: 1 Float1_entry: 2 subl $8, %esp 3 .L100: 4 fld1 5 subl $8, %esp 6 fstpl 0(%esp) 7 call sin 8 addl $8, %esp 9 fstpl 0(%esp) ;--- instead discarding value from FP stack O'Caml allocates ; space for result on the main stack, store this value to ; stack and after all discards it. 10 movl $1, %eax 11 addl $8, %esp 12 ret -- 2. passing FP parameter to stack is less efficient than possible: Ocaml currently generates this code for pushing float arguments. fldl
subl $8, %esp fstpl 0(%esp) While gcc generates two pushes pushl pushl or movl %address,%reg1 movl %address+4,%reg2 pushl %reg2 pushl %reg1 3. (less important) Ocaml never generate assembler trigonometric functions: fsin, fcos... Yes they violates ANSI rules, but their usage can improve perfomance of an application. Write simple C program with sin or cos usage and compile it with and without "-ffast-math" switch. The difference is about 25%. example.c: #include int main() { int i; volatile double d=1.0; for(i=0;i<10000000;i+=1) d=cos(sin(d)); return 0; } Regards, Anton Moscal Nickolay Kolchin