Profiling OCaml with gprof and jbuilder

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.

As an example program to profile, I will use a short code implementing the tak function of dear prof. Takeuchi.

(* 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 gmon.out. The next step is, as usual with gprof, to generate the profile from gmon.out

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 becomes

ocamlopt -p tak.ml -o tak -ccopt -no-pie

and by re-running the program and gprof, 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 ocamlopt_flags, and 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 compiling with ocamlopt directly. We can now compile our program with jbuilder.

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.

comments powered by Disqus
© 2023 Daniel Perez   Creative Commons License