That's the output of ghc -ddump-simpl. 2009/5/18 Sam Martin <[email protected]>: > 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: [email protected] 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 > [email protected] > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > _______________________________________________ > Haskell-Cafe mailing list > [email protected] > http://www.haskell.org/mailman/listinfo/haskell-cafe > >
-- Eugene Kirpichov Web IR developer, market.yandex.ru _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
