Memory use blowup with -O1 (versus -O0) in GHC 6.12.1/6.12.2

Hi, I've encountered an interesting issue with GHC 6.12.1 and 2 in which a small program compiles quickly without using loads of memory with optimization turned off, but with optimization (-O1) turned on, GHC's memory usage becomes very high (and compilation takes much much longer). $ time ghc -c -O0 Tst.hs real 0m0.107s user 0m0.073s sys 0m0.035s $ time ghc -c -O1 Tst.hs real 0m38.605s user 0m36.669s sys 0m1.923s Memory used by GHC looks like it tops out at 3G (in the -O1 case). Constraining the heap size to 1G causes compilation to fail: $ ghc +RTS -M1g -RTS -c -O1 Tst.hs Heap exhausted; Current maximum heap size is 1073741824 bytes (1024 MB); use `+RTS -M<size>' to increase it. (whereas, without optimization, a heap of 16m is sufficient) The module being compiled is (probably deceptively) simple: module Tst where import Merge data Rec1 = Rec1 !Int mkRec1 v = mk $ merge v () where mk (Tagged i :* ()) = Rec1 i but the devil is in the details of 'merge' (attached) which merges heterogeneous lists of values, using a lot of type level programming with type families. Does this sound like an known, open issue? I was unable to find anything in GHC Trac that looked similar. Thanks, Rob

On Mon, May 10, 2010 at 01:33:00PM -0400, Robert Greayer wrote:
I've encountered an interesting issue with GHC 6.12.1 and 2 in which a small program compiles quickly without using loads of memory with optimization turned off, but with optimization (-O1) turned on, GHC's memory usage becomes very high (and compilation takes much much longer).
I can reproduce this with the 6.12 branch, but in the HEAD compilation is fast, and works with "+RTS -M30M". Thanks Ian

Robert Great example! Your test case makes the type checker work hard to produce solve the type-equality constraints (and you have a lot of them); when pretty-printed it comes to 7000 lines! But these large proofs are readily simplified to something tiny, just a few lines. As luck would have it, I've already implemented a proof simplifier in the HEAD (it will appear in 6.14), and that makes short work of it. Everything goes through in a snap. Thanks for giving me such a convincing example of why a proof simplifier is Really Really worth it! Simon bash-3.2$ | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow- | haskell-users-bounces@haskell.org] On Behalf Of Robert Greayer | Sent: 10 May 2010 18:33 | To: glasgow-haskell-users@haskell.org | Subject: Memory use blowup with -O1 (versus -O0) in GHC 6.12.1/6.12.2 | | Hi, | | I've encountered an interesting issue with GHC 6.12.1 and 2 in which a | small program compiles quickly without using loads of memory with | optimization turned off, but with optimization (-O1) turned on, GHC's | memory usage becomes very high (and compilation takes much much | longer). | | $ time ghc -c -O0 Tst.hs | | real 0m0.107s | user 0m0.073s | sys 0m0.035s | | $ time ghc -c -O1 Tst.hs | | real 0m38.605s | user 0m36.669s | sys 0m1.923s | | Memory used by GHC looks like it tops out at 3G (in the -O1 case). | | Constraining the heap size to 1G causes compilation to fail: | | $ ghc +RTS -M1g -RTS -c -O1 Tst.hs | Heap exhausted; | Current maximum heap size is 1073741824 bytes (1024 MB); use `+RTS - | M<size>' to increase it. | | (whereas, without optimization, a heap of 16m is sufficient) | | The module being compiled is (probably deceptively) simple: | | module Tst where | import Merge | data Rec1 = Rec1 !Int | mkRec1 v = mk $ merge v () where mk (Tagged i :* ()) = Rec1 i | | but the devil is in the details of 'merge' (attached) which merges | heterogeneous lists of values, using a lot of type level programming | with type families. Does this sound like an known, open issue? I was | unable to find anything in GHC Trac that looked similar. | | Thanks, | Rob
participants (3)
-
Ian Lynagh
-
Robert Greayer
-
Simon Peyton-Jones