Add -pa and -V to the documentation of time profiling options.
[ghc-hetmet.git] / docs / users_guide / profiling.xml
index c30bd80..5fb53d0 100644 (file)
@@ -33,7 +33,9 @@
     <listitem>
       <para> Run your program with one of the profiling options, eg.
       <literal>+RTS -p -RTS</literal>.  This generates a file of
-      profiling information.</para>
+      profiling information.  Note that multi-processor execution
+      (e.g. <literal>+RTS -N2</literal>) is not supported while
+      profiling.</para>
       <indexterm><primary><option>-p</option></primary><secondary>RTS
       option</secondary></indexterm>
     </listitem>
@@ -240,9 +242,7 @@ MAIN                     MAIN             0    0.0   0.0    100.0 100.0
     although GHC does keep information about which groups of functions
     called each other recursively, this information isn't displayed in
     the basic time and allocation profile, instead the call-graph is
-    flattened into a tree.  The XML profiling tool (described in <xref
-    linkend="prof-xml-tool"/>) will be able to display real loops in
-    the call-graph.</para>
+    flattened into a tree.</para>
 
     <sect2><title>Inserting cost centres by hand</title>
 
@@ -263,7 +263,29 @@ MAIN                     MAIN             0    0.0   0.0    100.0 100.0
       in the profiling output, and
       <literal>&lt;expression&gt;</literal> is any Haskell
       expression.  An <literal>SCC</literal> annotation extends as
-      far to the right as possible when parsing.</para>
+      far to the right as possible when parsing. (SCC stands for "Set
+      Cost Centre").</para>
+
+      <para>Here is an example of a program with a couple of SCCs:</para>
+
+<programlisting>
+main :: IO ()
+main = do let xs = {-# SCC "X" #-} [1..1000000]
+          let ys = {-# SCC "Y" #-} [1..2000000]
+          print $ last xs
+          print $ last $ init xs
+          print $ last ys
+          print $ last $ init ys
+</programlisting>
+
+      <para>which gives this heap profile when run:</para>
+
+      <!-- contentwidth/contentheight don't appear to have any effect
+           other than making the PS file generation work, rather than
+           falling over.  The result seems to be broken PS on the page
+           with the image. -->
+      <imagedata fileref="prof_scc" contentwidth="645px"
+      contentdepth="428px"/>
 
     </sect2>
 
@@ -436,9 +458,10 @@ x = nfib 25
     <variablelist>
       <varlistentry>
        <term>
-          <option>-p</option> or <option>-P</option>:
+          <option>-p</option> or <option>-P</option> or <option>-pa</option>:
           <indexterm><primary><option>-p</option></primary></indexterm>
           <indexterm><primary><option>-P</option></primary></indexterm>
+          <indexterm><primary><option>-pa</option></primary></indexterm>
           <indexterm><primary>time profile</primary></indexterm>
         </term>
        <listitem>
@@ -450,21 +473,24 @@ x = nfib 25
          <para>The <option>-P</option> option produces a more
           detailed report containing the actual time and allocation
           data as well.  (Not used much.)</para>
-       </listitem>
-      </varlistentry>
 
-      <varlistentry>
-       <term>
-          <option>-px</option>:
-          <indexterm><primary><option>-px</option></primary></indexterm>
-        </term>
-       <listitem>
-         <para>The <option>-px</option> option generates profiling
-         information in the XML format understood by our new
-         profiling tool, see <xref linkend="prof-xml-tool"/>.</para>
+          <para>The <option>-pa</option> option produces the most detailed
+          report containing all cost centres in addition to the actual time
+          and allocation data.</para>
        </listitem>
       </varlistentry>
 
+     <varlistentry>
+       <term><option>-V<replaceable>secs</replaceable></option>
+       <indexterm><primary><option>-V</option></primary><secondary>RTS
+       option</secondary></indexterm></term>
+       <listitem>
+         <para>Sets the interval that the RTS clock ticks at, which is
+         also the sampling interval of the time and allocation profile.
+         The default is 0.02&nbsp;second.</para>
+       </listitem>
+     </varlistentry>
+
       <varlistentry>
        <term>
           <option>-xc</option>
@@ -520,6 +546,11 @@ x = nfib 25
       </listitem>
     </orderedlist>
 
+    <para>You might also want to take a look
+      at <ulink url="http://www.haskell.org/haskellwiki/Hp2any">hp2any</ulink>,
+      a more advanced suite of tools (not distributed with GHC) for
+      displaying heap profiles.</para>
+
     <sect2 id="rts-options-heap-prof">
       <title>RTS options for heap profiling</title>
 
@@ -725,7 +756,8 @@ x = nfib 25
             0.1&nbsp;second).  Fractions are allowed: for example
             <option>-i0.2</option> will get 5 samples per second.
             This only affects heap profiling; time profiles are always
-            sampled on a 1/50 second frequency.</para>
+            sampled with the frequency of the RTS clock. See
+            <xref linkend="prof-time-options"/> for changing that.</para>
          </listitem>
        </varlistentry>
 
@@ -961,48 +993,6 @@ x = nfib 25
 
   </sect1>
 
-  <sect1 id="prof-xml-tool">
-    <title>Graphical time/allocation profile</title>
-
-    <para>You can view the time and allocation profiling graph of your
-    program graphically, using <command>ghcprof</command>.  This is a
-    new tool with GHC 4.08, and will eventually be the de-facto
-    standard way of viewing GHC profiles<footnote><para>Actually this
-    isn't true any more, we are working on a new tool for
-    displaying heap profiles using Gtk+HS, so
-    <command>ghcprof</command> may go away at some point in the future.</para>
-      </footnote></para>
-
-    <para>To run <command>ghcprof</command>, you need
-    <productname>uDraw(Graph)</productname> installed, which can be
-    obtained from <ulink
-    url="http://www.informatik.uni-bremen.de/uDrawGraph/en/uDrawGraph/uDrawGraph.html"><citetitle>uDraw(Graph)</citetitle></ulink>.  Install one of
-    the binary
-    distributions, and set your
-    <envar>UDG_HOME</envar> environment variable to point to the
-    installation directory.</para>
-
-    <para><command>ghcprof</command> uses an XML-based profiling log
-    format, and you therefore need to run your program with a
-    different option: <option>-px</option>.  The file generated is
-    still called <filename>&lt;prog&gt;.prof</filename>.  To see the
-    profile, run <command>ghcprof</command> like this:</para>
-
-    <indexterm><primary><option>-px</option></primary></indexterm>
-
-<screen>
-$ ghcprof &lt;prog&gt;.prof
-</screen>
-
-    <para>which should pop up a window showing the call-graph of your
-    program in glorious detail.  More information on using
-    <command>ghcprof</command> can be found at <ulink
-    url="http://www.dcs.warwick.ac.uk/people/academic/Stephen.Jarvis/profiler/index.html"><citetitle>The
-    Cost-Centre Stack Profiling Tool for
-    GHC</citetitle></ulink>.</para>
-
-  </sect1>
-
   <sect1 id="hp2ps">
     <title><command>hp2ps</command>&ndash;&ndash;heap profile to PostScript</title>
 
@@ -1302,8 +1292,324 @@ to re-read its input file:
 </screen>
 </para>
 </sect2>
+  </sect1>
+
+  <sect1 id="hpc">
+    <title>Observing Code Coverage</title>
+    <indexterm><primary>code coverage</primary></indexterm>
+    <indexterm><primary>Haskell Program Coverage</primary></indexterm>
+    <indexterm><primary>hpc</primary></indexterm>
+
+    <para>
+      Code coverage tools allow a programmer to determine what parts of
+      their code have been actually executed, and which parts have
+      never actually been invoked.  GHC has an option for generating
+      instrumented code that records code coverage as part of the
+      <ulink url="http://www.haskell.org/hpc">Haskell Program Coverage
+      </ulink>(HPC) toolkit, which is included with GHC. HPC tools can
+      be used to render the generated code coverage information into
+      human understandable format.  </para>
+
+    <para>
+      Correctly instrumented code provides coverage information of two
+      kinds: source coverage and boolean-control coverage. Source
+      coverage is the extent to which every part of the program was
+      used, measured at three different levels: declarations (both
+      top-level and local), alternatives (among several equations or
+      case branches) and expressions (at every level).  Boolean
+      coverage is the extent to which each of the values True and
+      False is obtained in every syntactic boolean context (ie. guard,
+      condition, qualifier).  </para>
+
+    <para>
+      HPC displays both kinds of information in two primary ways:
+      textual reports with summary statistics (hpc report) and sources
+      with color mark-up (hpc markup).  For boolean coverage, there
+      are four possible outcomes for each guard, condition or
+      qualifier: both True and False values occur; only True; only
+      False; never evaluated. In hpc-markup output, highlighting with
+      a yellow background indicates a part of the program that was
+      never evaluated; a green background indicates an always-True
+      expression and a red background indicates an always-False one.
+    </para> 
+
+   <sect2><title>A small example: Reciprocation</title>
+
+    <para>
+     For an example we have a program, called Recip.hs, which computes exact decimal
+     representations of reciprocals, with recurring parts indicated in
+     brackets.
+    </para>
+<programlisting>
+reciprocal :: Int -> (String, Int)
+reciprocal n | n > 1 = ('0' : '.' : digits, recur)
+             | otherwise = error
+                 "attempting to compute reciprocal of number &lt;= 1"
+  where
+  (digits, recur) = divide n 1 []
+divide :: Int -> Int -> [Int] -> (String, Int)
+divide n c cs | c `elem` cs = ([], position c cs)
+              | r == 0      = (show q, 0)
+              | r /= 0      = (show q ++ digits, recur)
+  where
+  (q, r) = (c*10) `quotRem` n
+  (digits, recur) = divide n r (c:cs)
+
+position :: Int -> [Int] -> Int
+position n (x:xs) | n==x      = 1
+                  | otherwise = 1 + position n xs
+
+showRecip :: Int -> String
+showRecip n =
+  "1/" ++ show n ++ " = " ++
+  if r==0 then d else take p d ++ "(" ++ drop p d ++ ")"
+  where
+  p = length d - r
+  (d, r) = reciprocal n
+
+main = do
+  number &lt;- readLn
+  putStrLn (showRecip number)
+  main
+</programlisting>
+
+    <para>The HPC instrumentation is enabled using the -fhpc flag.
+    </para>
+
+<screen>
+$ ghc -fhpc Recip.hs --make 
+</screen>
+    <para>HPC index (.mix) files are placed placed in .hpc subdirectory. These can be considered like
+    the .hi files for HPC. 
+   </para>
+<screen>
+$ ./Recip
+1/3
+= 0.(3)
+</screen>
+    <para>We can generate a textual summary of coverage:</para>
+<screen>
+$ hpc report Recip
+ 80% expressions used (81/101)
+ 12% boolean coverage (1/8)
+      14% guards (1/7), 3 always True, 
+                        1 always False, 
+                        2 unevaluated
+       0% 'if' conditions (0/1), 1 always False
+     100% qualifiers (0/0)
+ 55% alternatives used (5/9)
+100% local declarations used (9/9)
+100% top-level declarations used (5/5)
+</screen>
+    <para>We can also generate a marked-up version of the source.</para>
+<screen>
+$ hpc markup Recip
+writing Recip.hs.html
+</screen>
+    <para>
+               This generates one file per Haskell module, and 4 index files,
+               hpc_index.html, hpc_index_alt.html, hpc_index_exp.html,
+               hpc_index_fun.html.
+       </para>
+     </sect2> 
+
+     <sect2><title>Options for instrumenting code for coverage</title>
+       <para>
+               Turning on code coverage is easy, use the -fhpc flag. 
+               Instrumented and non-instrumented can be freely mixed.
+               When compiling the Main module GHC automatically detects when there
+               is an hpc compiled file, and adds the correct initialization code.
+       </para>
+
+     </sect2>
+
+     <sect2><title>The hpc toolkit</title>
+
+      <para>
+      The hpc toolkit uses a cvs/svn/darcs-like interface, where a
+      single binary contains many function units.</para> 
+<screen>
+$ hpc 
+Usage: hpc COMMAND ...
+
+Commands:
+  help        Display help for hpc or a single command
+Reporting Coverage:
+  report      Output textual report about program coverage
+  markup      Markup Haskell source with program coverage
+Processing Coverage files:
+  sum         Sum multiple .tix files in a single .tix file
+  combine     Combine two .tix files in a single .tix file
+  map         Map a function over a single .tix file
+Coverage Overlays:
+  overlay     Generate a .tix file from an overlay file
+  draft       Generate draft overlay that provides 100% coverage
+Others:
+  show        Show .tix file in readable, verbose format
+  version     Display version for hpc
+</screen>
+
+     <para>In general, these options act on .tix file after an
+     instrumented binary has generated it, which hpc acting as a
+     conduit between the raw .tix file, and the more detailed reports
+     produced. 
+       </para>
+         
+       <para>
+               The hpc tool assumes you are in the top-level directory of
+               the location where you built your application, and the .tix
+               file is in the same top-level directory. You can use the
+               flag --srcdir to use hpc for any other directory, and use
+               --srcdir multiple times to analyse programs compiled from
+               difference locations, as is typical for packages.
+       </para>
+         
+       <para>
+       We now explain in more details the major modes of hpc.
+     </para>
+
+       <sect3><title>hpc report</title>
+               <para>hpc report gives a textual report of coverage. By default,
+                       all modules and packages are considered in generating report,
+                       unless include or exclude are used. The report is a summary
+                       unless the --per-module flag is used. The --xml-output option
+                       allows for tools to use hpc to glean coverage. 
+               </para> 
+<screen>
+$ hpc help report
+Usage: hpc report [OPTION] .. &lt;TIX_FILE&gt; [&lt;MODULE&gt; [&lt;MODULE&gt; ..]]
+
+Options:
+
+    --per-module                  show module level detail
+    --decl-list                   show unused decls
+    --exclude=[PACKAGE:][MODULE]  exclude MODULE and/or PACKAGE
+    --include=[PACKAGE:][MODULE]  include MODULE and/or PACKAGE
+    --srcdir=DIR                  path to source directory of .hs files
+                                  multi-use of srcdir possible
+    --hpcdir=DIR                  sub-directory that contains .mix files
+                                  default .hpc [rarely used]
+    --xml-output                  show output in XML
+</screen>
+       </sect3>
+       <sect3><title>hpc markup</title>
+               <para>hpc markup marks up source files into colored html.
+               </para>
+<screen>
+$ hpc help markup
+Usage: hpc markup [OPTION] .. &lt;TIX_FILE&gt; [&lt;MODULE&gt; [&lt;MODULE&gt; ..]]
+
+Options:
+
+    --exclude=[PACKAGE:][MODULE]  exclude MODULE and/or PACKAGE
+    --include=[PACKAGE:][MODULE]  include MODULE and/or PACKAGE
+    --srcdir=DIR                  path to source directory of .hs files
+                                  multi-use of srcdir possible
+    --hpcdir=DIR                  sub-directory that contains .mix files
+                                  default .hpc [rarely used]
+    --fun-entry-count             show top-level function entry counts
+    --highlight-covered           highlight covered code, rather that code gaps
+    --destdir=DIR                 path to write output to
+</screen>
 
+       </sect3>
+       <sect3><title>hpc sum</title>
+               <para>hpc sum adds together any number of .tix files into a single 
+               .tix file. hpc sum does not change the original .tix file; it generates a new .tix file. 
+               </para>
+<screen>
+$ hpc help sum
+Usage: hpc sum [OPTION] .. &lt;TIX_FILE&gt; [&lt;TIX_FILE&gt; [&lt;TIX_FILE&gt; ..]]
+Sum multiple .tix files in a single .tix file
+
+Options:
 
+    --exclude=[PACKAGE:][MODULE]  exclude MODULE and/or PACKAGE
+    --include=[PACKAGE:][MODULE]  include MODULE and/or PACKAGE
+    --output=FILE                 output FILE
+    --union                       use the union of the module namespace (default is intersection)
+</screen>
+       </sect3>
+       <sect3><title>hpc combine</title>
+               <para>hpc combine is the swiss army knife of hpc. It can be 
+                used to take the difference between .tix files, to subtract one
+               .tix file from another, or to add two .tix files. hpc combine does not
+               change the original .tix file; it generates a new .tix file. 
+               </para>
+<screen>
+$ hpc help combine
+Usage: hpc combine [OPTION] .. &lt;TIX_FILE&gt; &lt;TIX_FILE&gt;
+Combine two .tix files in a single .tix file
+
+Options:
+
+    --exclude=[PACKAGE:][MODULE]  exclude MODULE and/or PACKAGE
+    --include=[PACKAGE:][MODULE]  include MODULE and/or PACKAGE
+    --output=FILE                 output FILE
+    --function=FUNCTION           combine .tix files with join function, default = ADD
+                                  FUNCTION = ADD | DIFF | SUB
+    --union                       use the union of the module namespace (default is intersection)
+</screen>
+       </sect3>
+       <sect3><title>hpc map</title>
+               <para>hpc map inverts or zeros a .tix file. hpc map does not
+               change the original .tix file; it generates a new .tix file. 
+               </para>
+<screen>
+$ hpc help map
+Usage: hpc map [OPTION] .. &lt;TIX_FILE&gt; 
+Map a function over a single .tix file
+
+Options:
+
+    --exclude=[PACKAGE:][MODULE]  exclude MODULE and/or PACKAGE
+    --include=[PACKAGE:][MODULE]  include MODULE and/or PACKAGE
+    --output=FILE                 output FILE
+    --function=FUNCTION           apply function to .tix files, default = ID
+                                  FUNCTION = ID | INV | ZERO
+    --union                       use the union of the module namespace (default is intersection)
+</screen>
+       </sect3>
+       <sect3><title>hpc overlay and hpc draft</title>
+               <para>
+                       Overlays are an experimental feature of HPC, a textual description
+                       of coverage. hpc draft is used to generate a draft overlay from a .tix file,
+                       and hpc overlay generates a .tix files from an overlay.
+               </para>
+<screen>
+% hpc help overlay
+Usage: hpc overlay [OPTION] .. &lt;OVERLAY_FILE&gt; [&lt;OVERLAY_FILE&gt; [...]]
+
+Options:
+
+    --srcdir=DIR   path to source directory of .hs files
+                   multi-use of srcdir possible
+    --hpcdir=DIR   sub-directory that contains .mix files
+                   default .hpc [rarely used]
+    --output=FILE  output FILE
+% hpc help draft  
+Usage: hpc draft [OPTION] .. &lt;TIX_FILE&gt;
+
+Options:
+
+    --exclude=[PACKAGE:][MODULE]  exclude MODULE and/or PACKAGE
+    --include=[PACKAGE:][MODULE]  include MODULE and/or PACKAGE
+    --srcdir=DIR                  path to source directory of .hs files
+                                  multi-use of srcdir possible
+    --hpcdir=DIR                  sub-directory that contains .mix files
+                                  default .hpc [rarely used]
+    --output=FILE                 output FILE
+</screen>
+      </sect3>
+     </sect2>
+     <sect2><title>Caveats and Shortcomings of Haskell Program Coverage</title>
+         <para>
+               HPC does not attempt to lock the .tix file, so multiple concurrently running
+               binaries in the same directory will exhibit a race condition. There is no way
+               to change the name of the .tix file generated, apart from renaming the binary.
+               HPC does not work with GHCi.
+         </para>
+    </sect2>
   </sect1>
 
   <sect1 id="ticky-ticky">
@@ -1312,13 +1618,13 @@ to re-read its input file:
 
     <para>(ToDo: document properly.)</para>
 
-    <para>It is possible to compile Glasgow Haskell programs so that
+    <para>It is possible to compile Haskell programs so that
     they will count lots and lots of interesting things, e.g., number
     of updates, number of data constructors entered, etc., etc.  We
     call this &ldquo;ticky-ticky&rdquo;
     profiling,<indexterm><primary>ticky-ticky
     profiling</primary></indexterm> <indexterm><primary>profiling,
-    ticky-ticky</primary></indexterm> because that's the sound a Sun4
+    ticky-ticky</primary></indexterm> because that's the sound a CPU
     makes when it is running up all those counters
     (<emphasis>slowly</emphasis>).</para>
 
@@ -1326,25 +1632,52 @@ to re-read its input file:
     it is quite separate from the main &ldquo;cost-centre&rdquo;
     profiling system, intended for all users everywhere.</para>
 
-    <para>To be able to use ticky-ticky profiling, you will need to
-    have built appropriate libraries and things when you made the
-    system.  See &ldquo;Customising what libraries to build,&rdquo; in
-    the installation guide.</para>
-
-    <para>To get your compiled program to spit out the ticky-ticky
-    numbers, use a <option>-r</option> RTS
-    option<indexterm><primary>-r RTS option</primary></indexterm>.
-    See <xref linkend="runtime-control"/>.</para>
+    <para>
+      You don't need to build GHC, the libraries, or the RTS a special
+      way in order to use ticky-ticky profiling.  You can decide on a
+      module-by-module basis which parts of a program have the
+      counters compiled in, using the
+      compile-time <option>-ticky</option> option.  Those modules that
+      were not compiled with <option>-ticky</option> won't contribute
+      to the ticky-ticky profiling results, and that will normally
+      include all the pre-compiled packages that your program links
+      with.
+    </para>
+
+    <para>
+      To get your compiled program to spit out the ticky-ticky
+      numbers:
 
-    <para>Compiling your program with the <option>-ticky</option>
-    switch yields an executable that performs these counts.  Here is a
-    sample ticky-ticky statistics file, generated by the invocation
-    <command>foo +RTS -rfoo.ticky</command>.</para>
+      <itemizedlist>
+        <listitem>
+          <para>
+            Link the program with <option>-debug</option>
+            (<option>-ticky</option> is a synonym
+            for <option>-debug</option> at link-time).  This links in
+            the debug version of the RTS, which includes the code for
+            aggregating and reporting the results of ticky-ticky
+            profilng.
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Run the program with the <option>-r</option> RTS
+            option<indexterm><primary>-r RTS option</primary></indexterm>.
+            See <xref linkend="runtime-control"/>.
+          </para>
+        </listitem>
+      </itemizedlist>
+    </para>
 
+    <para>
+      Here is a sample ticky-ticky statistics file, generated by
+      the invocation
+      <command>foo +RTS -rfoo.ticky</command>.
+      </para>
+    
 <screen>
  foo +RTS -rfoo.ticky
 
-
 ALLOCATIONS: 3964631 (11330900 words total: 3999476 admin, 6098829 goods, 1232595 slop)
                                 total words:        2     3     4     5    6+
   69647 (  1.8%) function values                 50.0  50.0   0.0   0.0   0.0