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: 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
>