Dune: How to enable profiling?

Created on 10 Jan 2018  路  23Comments  路  Source: ocaml/dune

I would like to use ocamlprof.
Could not find in the manual.
Thanks,
F.

Most helpful comment

My current workflow to get profiling is:

  • add a gprof environment to the top-level dune file as outlined above which adds the -p flag when compiling native code and thus enabling profiling.
  • I usually select profiling using a Makefile such that I can select it easily from the command line.
PROFILE=dev

all:
  dune build --profile=$(PROFILE)
  • dune seems to pick up from this any required additional linking because the build seems to work just fine. When running the resulting binary, it creates a gmon.out file that can be analysed using gprof(1).
  • I can imaging adding more profiles, for example to profile for coverage. However, this typically will require more than just setting a flag. For example, bisect_ppxwould require setting up PPX preprocessing and enabling it via setting an environment variable. For me it would be fine to always run the PPX and to only enable it using an environment variable.

All 23 comments

This not supported at the moment. How does ocamlprof work, do you just replace ocamlc (ocamlopt?) by ocamlprof?

Not exactly: you replace ocamlc with ocamlcp (and ocamlopt with ocamloptp).
ocamlprof is the equivalent of gprof (i.e. the tool to visualize the execution profile).

Ok, this seems like a good fit for #391

You can ping me if it gets implemented, I will test its use for profiling.

+1. Support for profiling would be great.

@diml It might be possible to also address this with our cross compilation ability. Off the top of my head, it should be possible to define a target "profiling" context that replaces ocamlc and ocamlopt with their profiling alternatives. It's a bit annoying that this has to be accomplished through findlib toolchains, but this should all be possible now. The nice thing is also that you'll be building your profiled binaries using efficient preprocessors.

Ah, that's true. I think there should still be a way to use profiling without talking about cross-compilation (at least for configuring it) as it feels a bit weird, but in the meantime that's a good way to do it.

So, the following should work with the tip of jbuilder:

$ cat > `ocamlfind printconf conf`.d/profiling.conf <<EOF
ocamlc(profiling)="ocamlcp"
ocamlopt(profiling)="ocamloptp"
EOF
$ jbuilder build -x profiling

And the build artifacts will be stored in _build/default.profiling.

there is no profiling.conf file in my ~/.opam

Yes, that's expected. I'm suggesting to create one with this contents:

ocamlc(profiling)="ocamlcp"
ocamlopt(profiling)="ocamloptp"

Were there any updates on this matter?

Nope. Have you try the suggested workaround?

Moving forward, this functionality could be exposed via the env stanza.

The code snipped above seems to use a findlib.conf.d directory. Is this correct? It does not exist in my installation and the snippet would not create it.

Yh, you need to create it manually if it doesn't exist.

I think we should just add a configuration option for this.

How about adding the -p flag to the options and use dune build --profile=profile. Below is the top-level dune file which I use to define global flags:

(env
 (profile
  (ocamlopt_flags (:standard -p -w -27-32-52-33-34-37-39))
  (flags (:standard -w -27-32-52-33-34-37-39)))
 (dev
  (flags (:standard -w -27-32-52-33-34-37-39)))
 (release
  (flags (:standard -w -27-32-52-33-34-37-39))))

It's not as simple as setting a profile. This requires setting up a host/target context setup which is done via workspaces. I suppose we do this setup when the profile profile is selected, but it feels a bit magical and I'm not sure how it would work with explicit workspaces.

My current workflow to get profiling is:

  • add a gprof environment to the top-level dune file as outlined above which adds the -p flag when compiling native code and thus enabling profiling.
  • I usually select profiling using a Makefile such that I can select it easily from the command line.
PROFILE=dev

all:
  dune build --profile=$(PROFILE)
  • dune seems to pick up from this any required additional linking because the build seems to work just fine. When running the resulting binary, it creates a gmon.out file that can be analysed using gprof(1).
  • I can imaging adding more profiles, for example to profile for coverage. However, this typically will require more than just setting a flag. For example, bisect_ppxwould require setting up PPX preprocessing and enabling it via setting an environment variable. For me it would be fine to always run the PPX and to only enable it using an environment variable.

@lindig your current solution sounds quite good to me. In fact, I'm not even sure how we could improve it in dune. I suppose we could add a gprof profile by default, but it's pretty trivial to add one yourself as you can tell.

Could you comment on your workflow with ocamloptp and ocamlcp? It seems that there's quite a bit of profiling options so I'm not entirely sure how to consolidate things. For example, would we need a separate profile for these profiling tools as well?

Regarding bisect_ppx, it's a bit of a separate question. We'll definitely have a specialized profile for that. It's just that there are some complications in implementing it. It does not affect gprof, ocamlcp, etc.

I have never used ocamlcp with Dune (or otherwise, as far as I remember). Because it requires calling a different compiler binary, I would not know how to do it in Dune. Maybe it could be supported by exposing the name of the compiler as a variable such that it could be also redefined in a profile. An OCaml installation already has several binaries that do almost the same but could be selected by a user:

  • ocamlopt[p].{opt, byte}
  • ocamlc[p].{opt,byte}

ocamloptp does not accept -pp and thus is not compatible with PPX'ing. This will be quite a limitation for projects that are big enough such that profiling is interesting in the first place.

Not sure it is relevant: ocamloptp is implemented as an instrumentation phase:
https://github.com/ocaml/ocaml/blob/trunk/tools/ocamloptp.ml#L228-L232

I confirm that @diml's suggestion creates a profiling exe in _build/default.profiling/src/program.exe

Not that for time profiling, there are some info there:
https://daniel.perez.sh/blog/2018/ocaml-jbuild-gprof
Just add this line to the dune file:

  (ocamlopt_flags :standard -p)

Until I read through all of the comments here and tried the nth suggestion (thanks @lindig), my impression was that getting time profiling via dune was not readily possible.

So, just a suggestion: insofar as adding an easy -p flag to an env in the top-level dune file yields what I'm guessing most devs commonly think of as "profiling" (i.e. timings), that should probably be added to the official documentation and this issue closed. More sophisticated/obscure sorts of profiling could then be addressed separately.

It seems that OCaml 4.09 no longer supports gprof and therefore the -p flag (ocaml/ocaml#2314). As far as I can tell, this leaves ocamloptp et al., which, as mentioned before, are different frontends and don't support PPX, and so don't easily slot into a dune run?

Could somebody confirm that with OCaml 4.09 it becomes impractical to profile dune-based projects?

The argument for removing gprof support is:

The rationale is that there are better easy-to-use profilers out there now, such as perf for Linux and Instruments on macOS; and the gprof support has always been patchy across targets. We save a whole build of the runtime and simplify some other parts of the codebase by removing it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

erikmd picture erikmd  路  4Comments

jeremiedimino picture jeremiedimino  路  5Comments

bobot picture bobot  路  7Comments

c-cube picture c-cube  路  7Comments

bobbypriambodo picture bobbypriambodo  路  5Comments