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-30 (19:43) |
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