[GHC] #7367: Optimiser / Linker Problem on amd64

GHC ghc-devs at haskell.org
Tue Aug 27 13:53:26 UTC 2013


#7367: Optimiser / Linker Problem on amd64
--------------------------------------------+------------------------------
        Reporter:  wurmli                   |            Owner:
            Type:  bug                      |           Status:  new
        Priority:  normal                   |        Milestone:  7.8.1
       Component:  Build System             |          Version:  7.6.1
      Resolution:                           |         Keywords:
Operating System:  Linux                    |     Architecture:  x86_64
 Type of failure:  Runtime performance bug  |  (amd64)
       Test Case:                           |       Difficulty:  Unknown
        Blocking:                           |       Blocked By:
                                            |  Related Tickets:
--------------------------------------------+------------------------------

Comment (by simonpj):

 Ah, got it now, thanks.  Indeed, there is a real issue here.
 `genPermutations` looks like this:
 {{{
 genPermutations !n !l !r !perm !count = allocaArray n $ \ destF -> do
         let upd j !f run = do
                 p0 <- peekElemOff perm 0
                 if p0 == 0 then increment perm count >> run f else do
                         copyArray destF perm n
                         increment perm count
                         flopS destF $ \ flops ->
                                 run (f `mappend` F (checksum j flops)
 flops)
         let go j !f = if j >= r then return f else upd j f (go (j+1))
         go l mempty
  where
     checksum i f = if i .&. 1 == 0 then f else -f
 }}}
 Now, just inline `checksum` and that call to `flopS` looks like
 {{{
    flopS destF $ \ flops ->
         run (f `mappend` F (if  then flops else -flops) flops)
 }}}
 Now `flopS` really does call its argument many times, so work really is
 saved by lifting out the constant expression to get:
 {{{
    let lvl::Bool = j .&. 1 == 0
    in flopS destF $ \ flops ->
         run (f `mappend` F (if lvl then flops else -flops) flops)
 }}}
 As it happens, in this case allocating the thunk may be more expensive
 than repeating the computation, but that's a bit hard for GHC to work out.

 Ideas welcome.

 Simon

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7367#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler




More information about the ghc-tickets mailing list