Browse thread
Optimizing Float Ref's
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2009-08-31 (14:09) |
From: | Till Varoquaux <till@p...> |
Subject: | Re: [Caml-list] Optimizing Float Ref's |
True. All float records and float arrays are unboxed so modifications don't have to pass through caml_modify. A single cell array will still have dynamic bound checking so I would recommend going for the record. Till On Sun, Aug 30, 2009 at 3:43 PM, Yaron Minsky<yminsky@gmail.com> wrote: > 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 > > _______________________________________________ > 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 >