[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