[Haskell-cafe] RE: de-sugared code? (branch from: fast Eucl. dist. - Haskell vs C)

Sam Martin sam.martin at geomerics.com
Mon May 18 11:29:58 EDT 2009


Brilliant! Thanks.


-----Original Message-----
From: Don Stewart [mailto:dons at galois.com]
Sent: Mon 18/05/2009 16:21
To: Sam Martin
Cc: Kenneth Hoste; Haskell Cafe mailing list
Subject: Re: de-sugared code? (branch from: fast Eucl. dist. - Haskell vs C)
 
Yes, I use the ghc-core tool:

    http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ghc-core

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090518/1596ca8a/attachment.html


More information about the Haskell-Cafe mailing list