Gabriel -

On Tue, May 26, 2009 at 07:02:16PM +0200, Gabriel Kerneis wrote:
> I've been suffering performance issues with CIL recently. 30% of the
> time was spent in garbage collection.

        A while ago a faced similar problems.
That time, I tried three different approaches to
speed up the analysis.  From least effective to
most effective:

(1) Recompile the run-time environment of OCaml
with the best known combination of optimization
flags.  This may speed up the garbage collector
a little bit.

The improvement was noticeable in my case but

(2) Drastically increase the heap size.  (Of
course this action is limited by the amount of
memory in the target machines.)

I was lucky and the time spent in the GC dropped
significantly after increasing the heap size.

In the documentation of [tune_garbage_collector]
I have collected some of the scarce information
on tuning of the OCaml garbage collector that I
found on the web.

    (** Tune the garbage collector's parameters for the extremely large
        datasets we usually cope with.

        - [minor_heap_size]: 32Kwords
        - [major_heap_increment]: 62Kwords
        - [space_overhead]: 80%
        - [max_overhead]: 500%

        - Increasing [minor_heap_size] will reduce the time spent in both
          the minor GC and the major GC.  It is often (but not always)
          preferable to keep it small enough to fit in the cache of the
        - Increasing [major_heap_increment] reduces the number of times
          that [add_to_heap] is called.
        - Increasing [space_overhead] will reduce the time spent in the
          major GC.

        Inspect the GC statistics at the end of the program's run.  The
        most important figure is the ratio of [promoted_words] to
        [minor_words].  This should be as small as possible.  If it is
        more than 10%, the program spends too much time in the GC (both
        minor and major).  Increasing [minor_heap_size] often helps in
        this case. *)
    let tune_garbage_collector () =
      let gc = Gc.get () in
        Gc.set {
          gc with
            Gc.minor_heap_size = 64 * gc.Gc.minor_heap_size;
            Gc.major_heap_increment = 64 * gc.Gc.major_heap_increment;
            Gc.space_overhead = 2 * gc.Gc.space_overhead;
            Gc.max_overhead = 2 * gc.Gc.max_overhead;
            Gc.verbose = 0 (* useful value: 0x01d *)

(3) Rewrite the analysis to be less functional.


I had a functional implementation of my analysis
that used a lot of [Buffer]s for the output:
many of them and with a large total size.
Rewriting it to a more procedural style which
meant immediate output of the string data to the
results file dramatically reduced the load on
the GC, increased the performance a lot, and at
the same time reduced the program's memory


Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT 
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. 
CIL-users mailing list

Reply via email to