<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7654.12">
<TITLE>RE: de-sugared code? (branch from: fast Eucl. dist. - Haskell vs C)</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>Brilliant! Thanks.<BR>
<BR>
<BR>
-----Original Message-----<BR>
From: Don Stewart [<A HREF="mailto:dons@galois.com">mailto:dons@galois.com</A>]<BR>
Sent: Mon 18/05/2009 16:21<BR>
To: Sam Martin<BR>
Cc: Kenneth Hoste; Haskell Cafe mailing list<BR>
Subject: Re: de-sugared code? (branch from: fast Eucl. dist. - Haskell vs C)<BR>
<BR>
Yes, I use the ghc-core tool:<BR>
<BR>
&nbsp;&nbsp;&nbsp; <A HREF="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ghc-core">http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ghc-core</A><BR>
<BR>
sam.martin:<BR>
&gt; Hi Don (and cafe),<BR>
&gt;<BR>
&gt; Given the example you just posted, is there a simple way to generate the<BR>
&gt; de-sugared haskell / core / STG / labelled-assembly versions of a piece of<BR>
&gt; haskell code? For instance, how did you generate the content below? I guess<BR>
&gt; this is the core language version?<BR>
&gt;<BR>
&gt; I'm a C/C++ coder and looking for the equivalent of &quot;Show Disassembly&quot;.<BR>
&gt;<BR>
&gt; Cheers,<BR>
&gt; Sam<BR>
&gt;<BR>
&gt; -----Original Message-----<BR>
&gt; From: haskell-cafe-bounces@haskell.org on behalf of Don Stewart<BR>
&gt; Sent: Mon 18/05/2009 14:50<BR>
&gt; To: Kenneth Hoste<BR>
&gt; Cc: Haskell Cafe mailing list<BR>
&gt; Subject: Re: [Haskell-cafe] fast Eucl. dist. - Haskell vs C<BR>
&gt;<BR>
&gt; kenneth.hoste:<BR>
&gt; &gt; Hello,<BR>
&gt; &gt;<BR>
&gt; &gt; For a while now, I've been trying to come up with a fast Haskell-only<BR>
&gt; &gt; function which implements Euclidean distance in n-dimensional space.<BR>
&gt; &gt;<BR>
&gt; &gt; So far, I've been disappointed by the performance of my best effort<BR>
&gt; &gt; in Haskell, compared to C. I'm hoping some of the Haskell experts<BR>
&gt; &gt; and/or performance gurus on this list can help me out on resolving this,<BR>
&gt; &gt; and also maybe shed some light on some strange (imho) things I've run<BR>
&gt; &gt; into.<BR>
&gt; &gt;<BR>
&gt; &gt; My current best try uses the uvector package, has two 'vectors' of type<BR>
&gt; &gt; (UArr Double)&nbsp; as input, and relies on the sumU and zipWithU functions<BR>
&gt; &gt; which use streaming to compute the result:<BR>
&gt; &gt;<BR>
&gt; &gt; dist_fast :: UArr Double -&gt; UArr Double -&gt; Double<BR>
&gt; &gt; dist_fast p1 p2 = sumDs `seq` sqrt sumDs<BR>
&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where<BR>
&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sumDs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = sumU ds<BR>
&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = zipWithU euclidean p1 p2<BR>
&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; euclidean x y = d*d<BR>
&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where<BR>
&gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d = x-y<BR>
&gt;<BR>
&gt; The problem in your uvector code is the use of lists, rather than uvector<BR>
&gt; generators. Replace [1..n] with enumFromTo:<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; import Control.Monad<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; import System.Environment<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; import System.IO<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; import Data.Array.Vector<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; dist :: UArr Double -&gt; UArr Double -&gt; Double<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; dist p1 p2 = sumU (zipWithU euclidean p1 p2)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; euclidean x y = d*d where d = x-y<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; main = do<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [dim] &lt;- map read `fmap` getArgs<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print $<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dist<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (enumFromToFracU 1.0 dim)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (enumFromToFracU 1.0 dim)<BR>
&gt;<BR>
&gt; Now the entire thiing will fuse to a loop.<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $s$wfold_s1RR :: Double# -&gt; Double# -&gt; Double# -&gt; Double#<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $s$wfold_s1RR =<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ (sc_s1RH :: Double#)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (sc1_s1RI :: Double#)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (sc2_s1RJ :: Double#) -&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case &gt;## sc1_s1RI a5_s1QR of wild4_a1tn {<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; False -&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case &gt;## sc_s1RH a5_s1QR of wild5_X1vx {<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; False -&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let {<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x1_a1Jg [ALWAYS Just L] :: Double#<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x1_a1Jg = -## sc1_s1RI sc_s1RH } in<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $s$wfold_s1RR<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+## sc_s1RH 1.0)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+## sc1_s1RI 1.0)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+## sc2_s1RJ (*## x1_a1Jg x1_a1Jg));<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; True -&gt; sc2_s1RJ<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; True -&gt; sc2_s1RJ<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }; } in<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case $s$wfold_s1RR 1.0 1.0 0.0 of ww_s1QH { __DEFAULT -&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a19 (D# ww_s1QH)<BR>
&gt;<BR>
&gt; and this assembly:<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; $ ghc -O2 -fvia-C -optc-O3<BR>
&gt;<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1T9_info:<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5(%rbx), %xmm7<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ucomisd&nbsp;&nbsp;&nbsp;&nbsp; %xmm7, %xmm6<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ja&nbsp; .L15<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ucomisd&nbsp;&nbsp;&nbsp;&nbsp; %xmm7, %xmm5<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jbe .L18<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .L14:<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .L15:<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (%rbp), %xmm5<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leaq&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8(%rbp), %rbp<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp *(%rbp)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .L18:<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movapd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %xmm6, %xmm7<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %xmm5, %xmm7<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mulsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %xmm7, %xmm7<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (%rbp), %xmm7<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %xmm7, (%rbp)<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .LC0(%rip), %xmm7<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %xmm7, %xmm5<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %xmm7, %xmm6<BR>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp s1T9_info<BR>
&gt;<BR>
&gt; Which I'd wager will match the C, which has to allocate the two arrays (GHC<BR>
&gt; essentially decides it doesn't need the arrays any more.<BR>
&gt;<BR>
&gt; -- Don<BR>
&gt; _______________________________________________<BR>
&gt; Haskell-Cafe mailing list<BR>
&gt; Haskell-Cafe@haskell.org<BR>
&gt; <A HREF="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</A><BR>
&gt;<BR>
&gt;<BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>