#1890: Regression in mandelbrot benchmark due to inlining
-------------------------------+--------------------------------------------
    Reporter:  dons            |       Owner:                       
        Type:  bug             |      Status:  new                  
    Priority:  normal          |   Milestone:                       
   Component:  Compiler        |     Version:  6.8.1                
    Severity:  normal          |    Keywords:  inlining, performance
  Difficulty:  Unknown         |    Testcase:                       
Architecture:  x86_64 (amd64)  |          Os:  Unknown              
-------------------------------+--------------------------------------------
 The (rather delicate) mandelbrot benchmark on the Great Language Shootout
 shows a large regression between ghc 6.6 and ghc 6.8. The unfold
 function's inlining/worker wrapper changes quite a lot, in 6.8, wrt. the
 6.6 code.

 Here's the code:

 {{{
 {-# OPTIONS -fexcess-precision #-}
 --
 -- The Computer Language Shootout
 -- http://shootout.alioth.debian.org/
 --
 -- Contributed by Spencer Janssen, Trevor McCort, Christophe Poucet and
 Don Stewart
 --
 -- Must be compiled with the -fexcess-precision flag as a pragma. GHC
 -- currently doesn't recognise the -fexcess-precision flag on the command
 -- line (!).
 --
 -- The following flags are suggested when compiling:
 --
 --      -O -fglasgow-exts -optc-march=pentium4
 --      -fbang-patterns -funbox-strict-fields -optc-O2 -optc-mfpmath=sse
 -optc-msse2
 --

 import System
 import System.IO
 import Foreign
 import Foreign.Marshal.Array

 main = do
     w <- getArgs >>= readIO . head
     let n      = w `div` 8
         m  = 2 / fromIntegral w
     putStrLn ("P4\n"++show w++" "++show w)
     p <- mallocArray0 n
     unfold n (next_x w m n) p (T 1 0 0 (-1))

 ------------------------------------------------------------------------
 --
 -- compiled quite differently with ghc 6.8
 --
 -- This function is very sensitive to inlining
 --

 unfold :: Int -> (T -> Maybe (Word8,T)) -> Ptr Word8 -> T -> IO ()
 unfold !i !f !ptr !x0 = loop x0
   where
     loop !x = go ptr 0 x

     go !p !n !x = case f x of
         Just (w,y) | n /= i -> poke p w >> go (p `plusPtr` 1) (n+1) y
         Nothing             -> hPutBuf stdout ptr i
         _                   -> hPutBuf stdout ptr i >> loop x

 ------------------------------------------------------------------------

 --
 -- These are all compiled the same:
 --

 data T = T !Int !Int !Int !Double

 next_x :: Int -> Double -> Int -> T -> Maybe (Word8, T)
 next_x !w !iw !bw (T bx x y ci)
     | y  == w   = Nothing
     | bx == bw  = Just (loop_x w x 8 iw ci 0, T 1 0    (y+1)   (iw+ci))
     | otherwise = Just (loop_x w x 8 iw ci 0, T (bx+1) (x+8) y ci)

 loop_x :: Int -> Int -> Int -> Double -> Double -> Word8 -> Word8
 loop_x !w !x !n !iw !ci !b
     | x < w = if n == 0
                     then b
                     else loop_x w (x+1) (n-1) iw ci (b+b+v)
     | otherwise = b `shiftL` n
   where
     v = fractal 0 0 (fromIntegral x * iw - 1.5) ci 50

 fractal :: Double -> Double -> Double -> Double -> Int -> Word8
 fractal !r !i !cr !ci !k
     | r2 + i2 > 4 = 0
     | k == 0      = 1
     | otherwise   = fractal (r2-i2+cr) ((r+r)*i+ci) cr ci (k-1)
   where
     (!r2,!i2) = (r*r,i*i)
 }}}

 One change in 6.8 is that the shiftL is inlined (yay), and the other inner
 loops are compiled identically to Core, however, the unfold function gets
 moved around a lot.

 Benchmarking:

 {{{
 $ ghc-6.6.1 -O2 -fglasgow-exts -fbang-patterns -funbox-strict-fields B.hs
 -o B66  -no-recomp

 $ time ./B68 4000 > /dev/null ; time ./B66 4000 > /dev/null
 ./B68 4000 > /dev/null  5.39s user 0.10s system 100% cpu 5.489 total
 ./B66 4000 > /dev/null  3.67s user 0.07s system 100% cpu 3.736 total
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1890>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to