Version française
Home     About     Download     Resources     Contact us    
Browse thread
Optimizing Float Ref's
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Yaron Minsky <yminsky@g...>
Subject: Re: [Caml-list] Optimizing Float Ref's
Float refs are not unboxed automatically, because refs
Are polymorphic containers. If you create your own pseudo-ref, i.e., a  
record with a single mutable float field, then I believe you should  
get the behaviour you expect.

Come to think of it, I wonder if it would be better to implement ref  
on top of a single-cell array, since then everyone would get the float  
unboxing whenever applicable. I imagine there is some runtime overhead  
to this, though.

y


On Aug 28, 2009, at 4:32 PM, Will M Farr <farr@MIT.EDU> wrote:

> Hello all,
>
> I'm running OCaml 3.11.1, and I noticed something strange in some  
> native code for matrix multiply today.  The code was
>
> let mmmul store m1 m2 =
>  let (ni,nk) = dims m1 and
>      (nk2,nj) = dims m2 and
>      (sni,snj) = dims store in
>  assert(nk=nk2);
>  assert(ni=sni);
>  assert(nj=snj);
>  for i = 0 to ni - 1 do
>    let row1 = m1.(i) and
>        srow = store.(i) in
>    for j = 0 to nj - 1 do
>      let sum = ref 0.0 in   (* Un-boxed float ref? *)
>      for k = 0 to nk - 1 do
>        let row2 = Array.unsafe_get m2 k in
>        let x = Array.unsafe_get row1 k and
>            y = Array.unsafe_get row2 j in
>        sum := !sum +. x*.y
>      done;
>      Array.unsafe_set srow j !sum
>    done
>  done;
>  store
>
> (I compiled with ocamlopt.)  It multiplies the matrices (represented  
> as arrays of arrays of floats) m1 and m2 together and puts the  
> result into the matrix store.  Profiling the code, I noticed a call  
> to caml_modify during the execution of this function!  Turns out  
> that the culprit was the float ref "sum".  Changing to the following  
> code (which eliminates the float ref, and uses the <- and .( )  
> operators instead of unsafe_set and unsafe_get) eliminated that  
> call, and sped things up tremendously:
>
> let mmmul store m1 m2 =
>  let (ni,nk) = dims m1 and
>      (nk2,nj) = dims m2 in
>  for i = 0 to ni - 1 do
>    let row1 = m1.(i) and
>        srow = store.(i) in
>    for j = 0 to nj - 1 do
>      srow.(j) <- 0.0;
>      for k = 0 to nk - 1 do
>        let row2 = Array.unsafe_get m2 k in
>        let x = row1.(k) and
>            y = row2.(j) in
>        srow.(j) <- srow.(j) +. x*.y
>      done
>    done
>  done;
>  store
>
> But, I thought that float ref's were automatically unboxed by the  
> compiler when they didn't escape the local context.  Is this a  
> complier bug, is there a bad interaction with unsafe_get and  
> unsafe_set, or is there something else going on that I don't  
> understand?  Any enlightenment would be appreciated.
>
> Thanks!
> Will
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs