Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding output of GHC's +RTS -t -RTS option

Tags:

haskell

ghc

I'm benchmarking the memory consumption of a haskell programm compiled with GHC. In order to do so, I run the programm with the following command line arguments: +RTS -t -RTS. Here's an example output: <<ghc: 86319295256 bytes, 160722 GCs, 53963869/75978648 avg/max bytes residency (386 samples), 191M in use, 0.00 INIT (0.00 elapsed), 152.69 MUT (152.62 elapsed), 58.85 GC (58.82 elapsed) :ghc>>. According to the ghc manual, the output shows:

  • The total number of bytes allocated by the program over the whole run.
  • The total number of garbage collections performed.
  • The average and maximum "residency", which is the amount of live data in bytes. The runtime can only determine the amount of live data during a major GC, which is why the number of samples corresponds to the number of major GCs (and is usually relatively small).
  • The peak memory the RTS has allocated from the OS.
  • The amount of CPU time and elapsed wall clock time while initialising the runtime system (INIT), running the program itself (MUT, the mutator), and garbage collecting (GC).

Applied to my example, it means that my program shuffles 82321 MiB (bytes divided by 1024^2) around, performs 160722 garbage collections, has a 51MiB/72MiB average/maximum memory residency, allocates at most 191M memory in RAM and so on ...

Now I want to know, what »The average and maximum "residency", which is the amount of live data in bytes« is compared to »The peak memory the RTS has allocated from the OS«? And also: What uses the remaining space of roughly 120M?

I was pointed here for more information, but that does not state clearly, what I want to know. Another source (5.4.4 second item) hints that the 120M memory is used for garbage collection. But that is too vague – I need a quotable information source.

So please, is there anyone who could answer my questions with good sources as proofs?

Kind regards!

like image 963
user3389669 Avatar asked Sep 29 '22 21:09

user3389669


1 Answers

The "resident" size is how much live Haskell data you have. The amount of memory actually allocated from the OS may be higher.

  • The RTS allocates memory in "blocks". If your program needs 7.3 blocks of of RAM, the RTS has to allocate 8 blocks, 0.7 of which is empty space.

  • The default garbage collection algorithm is a 2-space collector. That is, when space A fills up, it allocates space B (which is totally empty) and copies all the live data out of space A and into space B, then deallocates space A. That means that, for a while, you're using 2x as much RAM as is actually necessary. (I believe there's a switch somewhere to use a 1-space algorithm which is slower but uses less RAM.)

There is also some overhead for managing threads (especially if you have lots), and there might be a few other things.

I don't know how much you already know about GC technology, but you can try reading these:

  • http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel-gc/par-gc-ismm08.pdf

  • http://www.mm-net.org.uk/workshop190404/GHC%27s_Garbage_Collector.ppt

like image 151
MathematicalOrchid Avatar answered Oct 05 '22 07:10

MathematicalOrchid