#3458: Allocation where none should happen
-------------------------------+--------------------------------------------
Reporter: guest | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 6.12 branch
Component: Compiler | Version: 6.10.4
Severity: normal | Resolution:
Keywords: | Difficulty: Unknown
Testcase: | Os: Linux
Architecture: x86_64 (amd64) |
-------------------------------+--------------------------------------------
Comment (by simonpj):
I've had a look at this. I ran it with
{{{
./runST 100000 > /dev/null
}}}
Interesting. The allocation you are concerned about arises from the local
'loop' function in 'pick'. GHC allocates a function closure for it, once
per call of 'pick', which isn't really necessary.
There are two ways to stop this happening. One way is to make 'loop' a
top level function like this
{{{
pick (c,p) r = myloop c p r 0
myloop c p r i = if r < unsafeAt p i
then fromIntegral $ unsafeAt c i :: Word8
else myloop c p r (i+1)
}}}
This reduces allocation from 35Mbytes to 3Mbytes, by getting rid of those
loop closures.
But this is not very cool. In fact 'loop' is totally tail-recursive, and
should never be heap allocated. It's very nearly a let-no-escape thing but
not quite. Here is a smaller example:
{{{
f x = let g y = if y then x else g y
in g x
}}}
If you compile with -ddump-stg you'll see that `g` gets the "let-no-
escape" property, which means that it doesn't get a heap closure allocated
for it.
But if you make this little change:
{{{
f x = let g y = if y then x else g y
in case g x of
True -> False
False -> True
}}}
then `g` doesn't get the let-no-escape property. And for good reason: you
can't just adjust the stack pointer and jump to g.
But you ''could'' do so if the 'let' was floated inwards, just before
core-to-stg, thus:
{{{
f x = case let g y = if y then x else g y
in g x
of
True -> False
False -> True
}}}
Now it has the let-no-escape property again.
I'd never really thought of that. Food for thought here.
(These remarks are intended mainly for me and other over-interested
parties. As a workaround to get your performance up, try the lambda-
lifting thing I show first.)
Simon
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3458#comment:5>
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