From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: ** X-Spam-Status: No, score=2.8 required=5.0 tests=DNS_FROM_RFC_POST,SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 8901FBC37 for ; Sun, 30 Aug 2009 21:43:29 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av4AAKtymkrRVd3KkWdsb2JhbACPfIFxiHg/AQEBAQkLCgcTA6ltgSeONgEDAgSEFgWBVYh/ X-IronPort-AV: E=Sophos;i="4.44,300,1249250400"; d="scan'208";a="45694108" Received: from mail-qy0-f202.google.com ([209.85.221.202]) by mail4-smtp-sop.national.inria.fr with ESMTP; 30 Aug 2009 21:43:28 +0200 Received: by qyk40 with SMTP id 40so2200823qyk.9 for ; Sun, 30 Aug 2009 12:43:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:references:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:x-mailer :mime-version:subject:date:cc; bh=kaId46U8SZIMenEgZVsBD/Q36mUwEHY7xLOPCuHmtJw=; b=ByVHjgtbQzgum4nfG4FVqUAGxX+qDV6iAdgqkzRVHUbNJF3Dz/iQgjTLb86jT66I9z u0/kyAe40AkosSyCauXACRXGNu8p9AYdrMfs9PPrCbtND1kM19tgiN5AErH25kMpFvBa 0eHSNZPCFdGb271tU0x82N+QYUpLEFPLX0qhQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=references:message-id:from:to:in-reply-to:content-type :content-transfer-encoding:x-mailer:mime-version:subject:date:cc; b=uvOI480LrETguEicgY7s3dwERm1mrupdnf50tNOjqL7gaDxtjGsr8nzm1wPk9jBp5q 4gYkxJeBTluDTXDj6mdBIXGGr8i+qYwdsfTcFA91X42JINNrxVkynFZvISgT0sU6OKm+ qGg2tNDxYLeNttifKdYq3+z5ZIq/zCFPN9Gv4= Received: by 10.224.45.34 with SMTP id c34mr2920810qaf.15.1251661407362; Sun, 30 Aug 2009 12:43:27 -0700 (PDT) Received: from ?10.85.161.90? (mobile-166-137-132-007.mycingular.net [166.137.132.7]) by mx.google.com with ESMTPS id 4sm6398545qwe.54.2009.08.30.12.43.24 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 30 Aug 2009 12:43:25 -0700 (PDT) References: Message-Id: From: Yaron Minsky To: Will M Farr In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit X-Mailer: iPhone Mail (7A400) Mime-Version: 1.0 (iPhone Mail 7A400) Subject: Re: [Caml-list] Optimizing Float Ref's Date: Sun, 30 Aug 2009 15:43:17 -0400 Cc: "" X-Spam: no; 0.00; yaron:01 minsky:01 yminsky:01 ref's:01 unboxed:01 mutable:01 unboxing:01 runtime:01 ocaml:01 dims:01 dims:01 ocamlopt:01 matrices:01 arrays:01 arrays:01 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