[GHC] #12893: Profiling defeats stream fusion when using vector library

GHC ghc-devs at haskell.org
Sun Dec 9 21:38:23 UTC 2018


#12893: Profiling defeats stream fusion when using vector library
-------------------------------------+-------------------------------------
        Reporter:  newhoggy          |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:  stream-fusion
                                     |  profiling
Operating System:  MacOS X           |         Architecture:  x86_64
 Type of failure:  Runtime           |  (amd64)
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by sgraf):

 * cc: sgraf, simonpj (added)


Comment:

 Replying to [comment:4 guaraqe]:
 > I think the problem that the OP is reporting is that there are no cost
 centers in the program, yet no optimization is done. There are no manual
 `SCC`s and compilation is done with `-fno-prof-count-entries  -fno-prof-
 cafs -fno-prof-auto -O2`, so we would expect that there would be no
 barriers for optimization.
 >
 > This can be wrong if for some reason the GHC flags are not passed to the
 `vector` library, and it is still being compiled with automatic cost
 centers, which would indeed block fusion. If that is the case, it would be
 nice to have a way to pass these flags all the way down.

 Indeed passing `-prof` will use profiling versions of libraries. So
 functions in `vector` will still contribute their cost-centres.

 I did some digging. It seems that with profiled `vector` libraries, small
 functions like
 [https://github.com/haskell/vector/blob/cc06420eaa597b85ffd8ded9f82aac1a3fc02c18/Data/Vector/Internal/Check.hs#L53
 doBoundsCheck] or the specialised call to `pure @Id` (from
 `Data.Vector.Fusion.Util`) are no longer inlined. Especially the fact that
 `pure @Id` is no longer inlined means that SpecConstr is having a hard
 time extending the call pattern for the crucial `Step` parameter through
 the `Id` constructor in calls like this:

 {{{
 jump $j_s8PT
   ((Data.Vector.Fusion.Util.$fMonadId1
       @ (Data.Vector.Fusion.Stream.Monadic.Step Double Double)
       (Data.Vector.Fusion.Stream.Monadic.Yield
           @ Double
           @ Double
           (GHC.Types.D# sc_s8Ur)
           (GHC.Types.D# (GHC.Prim.+## sc_s8Ur 1.0##))))
 }}}

 Note that `$fMonadId = pure @Id`. If `$fMonadId` was inlined, SpecConstr
 could probably see through the SCC and extend the call pattern to `Yield`.

 I'm not sure which part of the simplifier or whatever is responsible for
 refusing to inline `$fMonadId`, it's unfolding in the interface file is
 basically

 {{{
 \ @ a -> {__scc {Data.Vector.Fusion.Util.pure} True False} \ (v :: a) -> v
 }}}

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


More information about the ghc-tickets mailing list