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