[GHC] #7850: Strangely high memory usage on optimized Ackermann function

GHC cvs-ghc at haskell.org
Sat Apr 20 09:26:59 CEST 2013


#7850: Strangely high memory usage on optimized Ackermann function
------------------------------------+---------------------------------------
Reporter:  dolio                    |          Owner:                
    Type:  bug                      |         Status:  new           
Priority:  normal                   |      Component:  Compiler      
 Version:  7.6.2                    |       Keywords:                
      Os:  Linux                    |   Architecture:  x86_64 (amd64)
 Failure:  Runtime performance bug  |      Blockedby:                
Blocking:                           |        Related:                
------------------------------------+---------------------------------------
 Greetings.

 The following post on stack overflow demonstrates some strange behavior
 in, at least, recent GHC versions (7.4.2 on):

 [http://stackoverflow.com/questions/16115815/ackermann-very-inefficient-
 with-haskell-ghc]

 The program in question is simple:

 {{{
 main = print $ ack 4 1

 ack :: Int -> Int -> Int
 ack 0 !n = n+1
 ack m  0 = ack (m-1) 1
 ack m  n = ack (m-1) $ ack m (n-1)
 }}}

 Here are the properties I've been able to deduce so far:

 1) When compiled without optimizations, the program uses almost no memory,
 but of course takes a while.

 2) When compiled with optimizations (-O and above), the program eats
 memory at a staggering rate. It easily freezes my machine in a matter of
 seconds.

 3) -ddump-simpl reveals that the loop is completely unboxed, operating
 only on Int#. -ddump-prep also shows no lets where allocation would
 presumably happen.

 4) Setting a maximum heap size typically seems to have no effect. When I
 set it to the minimum heap size with -M4096, even the optimized program
 seems to run in constant space most of the time. However, using something
 like -M1000000 seems to result in the outrageous memory usage, and the RTS
 never catches that far more than 1 megabyte of memory is being used. I had
 to convince myself that the flag actually does something with another test
 program.

 5) The standard bounded stack also does nothing.

 So, we seem to have a program that is allocating vast amounts of
 (ostensibly) non-heap, non-stack memory; but only when optimized.

 I believe I once set the maximum heap to 40960B, and killed the program
 before it killed my machine. On exiting, I got a heap overflow error. So,
 my initial stab would be that the completely unboxed loop somehow ''is''
 allocating in the heap, but somehow not in a way that ever allows the
 garbage collector or heap overflow check to run (similar to how a non-
 allocating loop can block any thread preemption). That's a wild guess,
 though.

 I'm unable to easily investigate the behavior on older GHC versions,
 unfortunately. So I'm unsure how far back this behavior goes. If I've
 missed something obvious, I apologize, but this seems like very odd
 behavior to me.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7850>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the ghc-tickets mailing list