From: simonpj Date: Fri, 10 Jan 2003 16:10:00 +0000 (+0000) Subject: [project @ 2003-01-10 16:10:00 by simonpj] X-Git-Tag: Approx_11550_changesets_converted~1270 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=2d6705ca56516c75c2f18c811f38c6ba7be02329;p=ghc-hetmet.git [project @ 2003-01-10 16:10:00 by simonpj] Add notes on real-time profiling from Jan-Willhem --- diff --git a/ghc/docs/users_guide/profiling.sgml b/ghc/docs/users_guide/profiling.sgml index b89cf65..85d4f8a 100644 --- a/ghc/docs/users_guide/profiling.sgml +++ b/ghc/docs/users_guide/profiling.sgml @@ -843,6 +843,10 @@ x = nfib 25 information simultaneously. + + + + @@ -1064,6 +1068,132 @@ hp2ps [flags] [<file>[.hp]] + + + + Manipulating the hp file + +(Notes kindly offered by Jan-Willhem Maessen.) + + +The FOO.hp file produced when you ask for the +heap profile of a program FOO is a text file with a particularly +simple structure. Here's a representative example, with much of the +actual data omitted: + +JOB "FOO -hC" +DATE "Thu Dec 26 18:17 2002" +SAMPLE_UNIT "seconds" +VALUE_UNIT "bytes" +BEGIN_SAMPLE 0.00 +END_SAMPLE 0.00 +BEGIN_SAMPLE 15.07 + ... sample data ... +END_SAMPLE 15.07 +BEGIN_SAMPLE 30.23 + ... sample data ... +END_SAMPLE 30.23 +... etc. +BEGIN_SAMPLE 11695.47 +END_SAMPLE 11695.47 + +The first four lines (JOB, DATE, SAMPLE_UNIT, VALUE_UNIT) form a +header. Each block of lines starting with BEGIN_SAMPLE and ending +with END_SAMPLE forms a single sample (you can think of this as a +vertical slice of your heap profile). The hp2ps utility should accept +any input with a properly-formatted header followed by a series of +*complete* samples. + + + + + Zooming in on regions of your profile + + +You can look at particular regions of your profile simply by loading a +copy of the .hp file into a text editor and deleting the unwanted +samples. The resulting .hp file can be run through hp2ps and viewed +or printed. + + + + + Viewing the heap profile of a running program + + +The .hp file is generated incrementally as your +program runs. In principle, running hp2ps on the incomplete file +should produce a snapshot of your program's heap usage. However, the +last sample in the file may be incomplete, causing hp2ps to fail. If +you are using a machine with UNIX utilities installed, it's not too +hard to work around this problem (though the resulting command line +looks rather Byzantine): + + head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ + | hp2ps > FOO.ps + + +The command fgrep -n END_SAMPLE FOO.hp finds the +end of every complete sample in FOO.hp, and labels each sample with +its ending line number. We then select the line number of the last +complete sample using tail and cut. This is used as a +parameter to head; the result is as if we deleted the final +incomplete sample from FOO.hp. This results in a properly-formatted +.hp file which we feed directly to hp2ps. + + + + Viewing a heap profile in real time + + +The gv and ghostview programs +have a "watch file" option can be used to view an up-to-date heap +profile of your program as it runs. Simply generate an incremental +heap profile as described in the previous section. Run gv on your +profile: + + gv -watch -seascape FOO.ps + +If you forget the -watch flag you can still select +"Watch file" from the "State" menu. Now each time you generate a new +profile FOO.ps the view will update automatically. + + + +This can all be encapsulated in a little script: + + #!/bin/sh + head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ + | hp2ps > FOO.ps + gv -watch -seascape FOO.ps & + while [ 1 ] ; do + sleep 10 # We generate a new profile every 10 seconds. + head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ + | hp2ps > FOO.ps + done + +Occasionally gv will choke as it tries to read an incomplete copy of +FOO.ps (because hp2ps is still running as an update +occurs). A slightly more complicated script works around this +problem, by using the fact that sending a SIGHUP to gv will cause it +to re-read its input file: + + #!/bin/sh + head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ + | hp2ps > FOO.ps + gv FOO.ps & + gvpsnum=$! + while [ 1 ] ; do + sleep 10 + head -`fgrep -n END_SAMPLE FOO.hp | tail -1 | cut -d : -f 1` FOO.hp \ + | hp2ps > FOO.ps + kill -HUP $gvpsnum + done + + + + +