Thanks to all who have replied. I didn't realize that references were always boxed (I thought that, internally, a reference was implemented as a one-element array, and therefore float refs would benefit from the automatic unboxing of float arrays). That's good to know. Will On Aug 31, 2009, at 10:09 AM, Till Varoquaux wrote: > 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 > 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 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 >>