I am currently using OCaml for part of my research and ran into more trouble than expected when trying to profile my program. This post details step by step how to compile an OCaml program using dune(jbuilder) to profile the binary using gprof.
(* tak.ml *) let rec tak x y z = if x <= y then y else tak (tak (x-1) y z) (tak (y-1) z x) (tak (z-1) x y) let () = print_endline (string_of_int (tak 18 12 6))
First, we will compile with the
-p option of
ocamlopt to turn on profiling
and run the program.
ocamlopt -p tak.ml -o tak ./tak
This should hopefully output
18 and create a file called
The next step is, as usual with
gprof, to generate the profile from
gprof tak gmon.out > profile.txt
If the profile looks good, then you can skip the next step. If, as on my
computer, you get an empty profile, then you probably have a buggy version of
gcc. A workaround seems to be to disable position independent code with the
-no-pie option, although I am not sure exactly why. The compile command then
ocamlopt -p tak.ml -o tak -ccopt -no-pie
and by re-running the program and
profile.txt should now actually
contain the program profile.
The last step is to get this working with
jbuilder by telling it to pass
the above options to
ocamlopt. This can be done with the
jbuild file can therefore be defined as follow.
(jbuild_version 1) (executable ( (name tak) (ocamlopt_flags (:standard -p -ccopt -no-pie)) ))
Note that you can remove the
-ccopt -no-pie part if you did not need it when
ocamlopt directly. We can now compile our program with
rm tak tak.cm* tak.o gmon.out profile.txt # cleanup first jbuilder build tak.exe
and we should be able to generate a profile.
./_build/default/tak.exe gprof _build/default/tak.exe gmon.out > profile.txt
Although I did not try it, it seems that it should be possible to
change the flags used by
jbuilder using command line arguments, so it
could also be worth trying in combination with the steps described above.