caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: ygrek <ygrekheretix@gmail.com>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Average cost of the OCaml GC
Date: Fri, 12 Nov 2010 23:54:30 +0200	[thread overview]
Message-ID: <20101112235430.288f415b.ygrekheretix@gmail.com> (raw)
In-Reply-To: <AANLkTinepB+CydLrS5fPC4RzHikO5ANVkfDgQoaGk3_h@mail.gmail.com>

On Fri, 12 Nov 2010 12:27:40 -0500
Jianzhou Zhao <jianzhou@seas.upenn.edu> wrote:

> Do we still have other methods to debug such problems? Is it possible
> to know when and where GC runs, say, the number of times GC works
> after a particular usr-defined function? If this is possible, I was
> wondering if we can see which function in my code behave wrong.

Below is straghtforward "GC diffing" code which helps me to pinpoint excessive GC 
(like the ExtLib.String.nsplit in example).

$ cat a.ml 

open Printf
open Gc

let bytes_string_f f = (* oh ugly *)
  let a = abs_float f in
  if a < 1024. then sprintf "%dB" (int_of_float f) else
  if a < 1024. *. 1024. then sprintf "%dKB" (int_of_float (f /. 1024.)) else
  if a < 1024. *. 1024. *. 1024. then sprintf "%.1fMB" (f /. 1024. /. 1024.) else
  sprintf "%.1fGB" (f /. 1024. /. 1024. /. 1024.)

let bytes_string x = bytes_string_f (float_of_int x)

let caml_words_f f =
  bytes_string_f (f *. (float_of_int (Sys.word_size / 8)))

let caml_words x = caml_words_f (float_of_int x)

let gc_diff st1 st2 =
  let allocated st = st.minor_words +. st.major_words -. st.promoted_words in
  let a = allocated st2 -. allocated st1 in
  let minor = st2.minor_collections - st1.minor_collections in
  let major = st2.major_collections - st1.major_collections in
  let compact = st2.compactions - st1. compactions in
  let heap = st2.heap_words - st1.heap_words in
  sprintf "allocated %10s, heap %10s, collection %d %d %d" (caml_words_f a) (caml_words heap) compact major minor

let gc_show name f x =
  let st = Gc.quick_stat () in
  Std.finally (fun () -> let st2 = Gc.quick_stat () in 
    eprintf "GC DIFF %s : %s\n" name (gc_diff st st2)) f x

let () =
  let _ = gc_show "split" (ExtLib.String.nsplit (String.make 10000 'a')) "a" in
  gc_show "compact" Gc.compact ()

$ ocamlfind ocamlopt -linkpkg -package extlib a.ml -o a
$ ./a 
GC DIFF split : allocated     48.1MB, heap     48.0MB, collection 0 21 373
GC DIFF compact : allocated       240B, heap    -48.0MB, collection 1 2 0

-- 
 ygrek
 http://ygrek.org.ua


  reply	other threads:[~2010-11-12 21:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-11  3:59 Jianzhou Zhao
2010-11-11  9:08 ` [Caml-list] " Goswin von Brederlow
2010-11-11 13:52   ` Jianzhou Zhao
2010-11-11 14:14     ` Michael Ekstrand
2010-11-11 20:11     ` Goswin von Brederlow
2010-11-12 17:27       ` Jianzhou Zhao
2010-11-12 21:54         ` ygrek [this message]
2010-11-16 10:02         ` Goswin von Brederlow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101112235430.288f415b.ygrekheretix@gmail.com \
    --to=ygrekheretix@gmail.com \
    --cc=caml-list@yquem.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).