Version française
Home     About     Download     Resources     Contact us    
Browse thread
memory profiling
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Sylvain Le Gall <sylvain@l...>
Subject: Re: memory profiling
Hello,

On 05-05-2009, Christoph Bauer <christoph.bauer@lmsintl.com> wrote:
> Hi,
>
> what is the best option to do memory profiling with ocaml?
> Is there a patch of ocaml-memprof for 3.11.0? What about
> objsize?
>

I use a more simple approach (though I have used objsize to estimate
some datastructure size, but only in the toplevel): GC allocation rate.

You can override a little ocaml-benchmark to measure the allocation rate
of the GC. This gives you a pretty good understanding on the fact you
are allocating too much or not.

Regards,
Sylvain Le Gall

ps: here is a part of my benchmarkExt.ml file


(** Benchmark extension
    @author Sylvain Le Gall
  *)

open Benchmark;;

type t =
    {
      benchmark: Benchmark.t;
      memory_used: float;
    }
;;

let gc_wrap f x =
  (* Extend sample to add GC stat *)
  let add_gc_stat memory_used samples =
    List.map 
      (fun (name, lst) ->
         name,
         List.map 
           (fun bt -> 
              { 
                benchmark = bt; 
                memory_used = memory_used;
              }
           )
           lst
      )
      samples
  in

  (* Call throughput1 and add GC stat *)
  let () = 
    print_string "Cleaning memory before benchmark"; print_newline ();    
    Gc.full_major ()
  in
  let allocated_before = 
    Gc.allocated_bytes ()
  in
  let samples =
    f x
  in
  let () = 
    print_string "Cleaning memory after benchmark"; print_newline ();
    Gc.full_major ()
  in
  let memory_used = 
    ((Gc.allocated_bytes ()) -. allocated_before) 
  in
    add_gc_stat memory_used samples
;;

let throughput1
      ?min_count ?style
      ?fwidth    ?fdigits
      ?repeat    ?name
      seconds 
      f x =
 
  (* Benchmark throughput1 as it should be called *) 
  gc_wrap 
    (throughput1
       ?min_count ?style
       ?fwidth    ?fdigits
       ?repeat    ?name
       seconds f) x
;;

let throughputN 
      ?min_count ?style
      ?fwidth    ?fdigits
      ?repeat    
      seconds name_f_args =
  List.flatten
    (List.map
       (fun (name, f, args) ->
         throughput1 
           ?min_count ?style
           ?fwidth    ?fdigits
           ?repeat    ~name:name
           seconds f args)
       name_f_args)
;;

let latency1 
      ?min_cpu ?style 
      ?fwidth  ?fdigits 
      ?repeat  n 
      ?name    f x =
  gc_wrap 
    (latency1
      ?min_cpu ?style 
      ?fwidth  ?fdigits 
      ?repeat  n 
      ?name    f) x
;;

let latencyN 
      ?min_cpu ?style 
      ?fwidth  ?fdigits 
      ?repeat  
      n name_f_args =
  List.flatten
    (List.map
       (fun (name, f, args) ->
         latency1 
           ?min_cpu   ?style
           ?fwidth    ?fdigits
           ?repeat    ~name:name
           n          f args)
       name_f_args)
;;