Hi Christoph, the extra code looks very much like an allocation on the minor heap: sub    $0x10,%r15 lea    0x25c7b6(%rip),%rax cmp    (%rax),%r15 jb     404a8a lea    0x8(%r15),%rax movq   $0x4fd,-0x8(%rax) r15 points to the used area of the minor heap - by decrementing it you get an additional block of memory. It is compared against the beginning of the heap to check whether GC is needed. The constant 0x4fd is the header of the new block (which must be always initialized). From the source code, it remains unclear for what this is used. Obviously, the compiler runs out of registers, and moves some values to the minor heap (temporarily). When you call a C function like cos it is likely that this happens because the C calling conventions do not preserve the FP registers (xmm*). This could be improved if the OCaml compiler tried alternate places for temporarily storing FP values:  - int registers (which is perfectly possible on 64 bit platforms).    A number of int registers survive C calls.  - stack To my knowledge, the OCaml compiler never tries this (but this could be out of date). This is a fairly specific optimization that makes mostly sense for purely iterating or aggregating functions like yours that do not store FP values away. Gerd Am Samstag, den 17.12.2016, 14:02 +0100 schrieb Christoph Höger: > Ups. Forgot the actual examples. > > Am 17.12.2016 um 14:01 schrieb Christoph Höger: > > > > Dear all, > > > > find attached two simple runge-kutta iteration schemes. One is > > written > > in C, the other in OCaml. I compared the runtime of both and gcc (- > > O2) > > produces an executable that is roughly 30% faster (to be more > > precise: > > 3.52s vs. 2.63s). That is in itself quite pleasing, I think. I do > > not > > understand however, what causes this difference. Admittedly, the > > generated assembly looks completely different, but both compilers > > inline > > all functions and generate one big loop. Ocaml generates a lot more > > scaffolding, but that is to be expected. > > > > There is however an interesting particularity: OCaml generates 6 > > calls > > to cos, while gcc only needs 3 (and one direct jump). Surprisingly, > > there are also calls to cosh, acos and pretty much any other > > trigonometric function (initialization of constants, maybe?) > > > > However, the true culprit seems to be an excess of instructions > > between > > the different calls to cos. This is what happens between the first > > two > > calls to cos: > > > > gcc: > > jmpq   400530 > > nop > > nopw   %cs:0x0(%rax,%rax,1) > > > > sub    $0x38,%rsp > > movsd  %xmm0,0x10(%rsp) > > movapd %xmm1,%xmm0 > > movsd  %xmm2,0x18(%rsp) > > movsd  %xmm1,0x8(%rsp) > > callq  400530 > > > > ocamlopt: > > > > callq  401a60 > > mulsd  (%r12),%xmm0 > > movsd  %xmm0,0x10(%rsp) > > sub    $0x10,%r15 > > lea    0x25c7b6(%rip),%rax > > cmp    (%rax),%r15 > > jb     404a8a > > lea    0x8(%r15),%rax > > movq   $0x4fd,-0x8(%rax) > > > > movsd  0x32319(%rip),%xmm1 > > > > movapd %xmm1,%xmm2 > > mulsd  %xmm0,%xmm2 > > addsd  0x0(%r13),%xmm2 > > movsd  %xmm2,(%rax) > > movapd %xmm1,%xmm0 > > mulsd  (%r12),%xmm0 > > addsd  (%rbx),%xmm0 > > callq  401a60 > > > > > > Is this caused by some underlying difference in the representation > > of > > numeric values (i.e. tagged ints) or is it reasonable to attack > > this > > issue as a hobby experiment? > > > > > > thanks for any advice, > > > > Christoph > > > -- ------------------------------------------------------------ Gerd Stolpmann, Darmstadt, Germany gerd@gerd-stolpmann.de My OCaml site: http://www.camlcity.org Contact details: http://www.camlcity.org/contact.html Company homepage: http://www.gerd-stolpmann.de ------------------------------------------------------------