then just using
external call_1 : float -> float = "call_1"
call_1
. However these calls are not direct. They go via an OCaml runtime function called caml_c_call
. This is a tiny bit of assembler, so the overhead isn't large, but it does use a computed jump which on many processors is quite slow.Luckily this indirection is only needed in order to set up the garbage collector. If your C function won't perform any OCaml allocations, then you don't need this, and you can tell OCaml to jump directly to your C function like this:
external call_2 : float -> float = "call_2" "noalloc"
Let's compare the generated assembly code for the calls in both cases:
Normal "noalloc"
pushl %eax pushl %eax
movl $call_1, %eax call call_2
call caml_c_call addl $4, %esp
addl $4, %esp
...
caml_c_call:
movl (%esp), %edx
movl %edx, G(caml_last_return_address)
leal 4(%esp), %edx
movl %edx, G(caml_bottom_of_stack)
jmp *%eax
As you can see, the "noalloc" version is much shorter.
3 comments:
There is also "float" which allows calling C functions with floats completely unboxed. As I understand, though, all values involved must be floats for this to work.
A message from Xavier Leroy on the mailing list is here:
http://groups.google.com/group/fa.caml/msg/977d7ccaaf61b223?hl=en
Cool!
Richard, but where do you find out about this feature? The documentation, I found nothing about it.
alermo:
"noalloc", and "float" as mentioned by Hezekiah, are not documented in the manual, but are both widely used in the stdlib and in external libraries.
Post a Comment