<!doctype book system "ozdoc.dtd" [
<!-- $Id: profiler.sgml,v 1.12 1999/12/01 21:50:45 kornstae Exp $ -->

<!-- Extension to the DTD -->
<!entity % proglang.values.local "|sh">
<!ENTITY emdash PI "emdash">
<!ENTITY endash PI "endash">
<!entity ie PI "ie">
<!entity eg PI "eg">
<!-- Abbreviations -->
<!-- Processing Instructions -->

]>

<book proglang=oz>
  <front>
    <meta name=ozversion value="3.0">
    <meta name=status value=draft>
    <meta name="proglang.mode" arg1="sh" arg2="shell-script-mode">
    <title/The Mozart Profiler/
    <author.extern to="author.db" key="Denys.Duchier">
    <author.extern to="author.db" key="Benjamin.Lorenz">
    <author.extern to="author.db" key="Ralf.Scheidhauer">
    <abstract>
      This manual describes the profiler for the Mozart programming
      system. With its help you can optimize your Oz applications.  It
      mainly counts procedure applications and measures their memory
      consumption, presenting its calculations using nice,
      clickable bar charts.
    </abstract>
  <body>
    <chapter>
      <title/What Is Profiling/
      <p>Once your application works, you may wish to optimize it for
speed and memory consumption.  For this, you need to identify the
parts of your application that may significantly benefit from such
optimizations; it would be pointless to optimize a procedure that is
called only once.  Profiling automatically instruments your program to
gather statistical data on procedure invocations and memory
allocation.</p>
      <p>The profiler collects information in a per procedure basis.
This information consists of the following quantities:
<list>
        <entry /<em>heap</em>/
	  <item>Heap memory allocated by the procedure
	  </item>
	 <entry/<em>calls</em>/
	    <item>How many times the procedure was called</item>
	 <entry/<em>samples</em>/
	  <item>Statistical estimation of the time spent in the
procedure. This works as follows: every 10ms a signal is delivered and
the emulator increases the <q/samples/ counter of the procedure
currently executing.</item>
	 <entry/<em>closures</em>/
	  <item>How many times the corresponding closure was created. 
	  Note that nested procedure declarations like <<Bar>> in
	  <<<
proc {Foo X Y}
  proc {Bar U V} ... end
  ...
end>>>
          both consume runtime and memory since a new closure for <<Bar>> has 
	  to be created at runtime whenever <<Foo>> ist called. So one might consider
	  lifting the definition of <<Bar>>. 
	  </item>
	</list></p>
	
    </chapter>

    <chapter>
      <title/How To Compile For Profiling/
      <p>In order to gather the profiling information, your code has
to be instrumented with additional profiling code.  This code is
automatically inserted by the compiler when it is invoked with the
<code proglang=sh/--profiler/ option.  This option can also be
abbreviated <code proglang=sh/-p/.  There is however an unfortunate
limitation when compiling code for profiling: tail-call optimization
is turned off (except for self applications). Besides this
instrumented code runs in general a bit slower than code that was not
compiled for profiling.</p>
      <p>As an example, let's consider the following rather pointless
application below.  I call it <q/The 3 Little Piggies/, and it does
nothing but waste time and memory:
<code.extern display to="piggies.oz">
The application can be compiled for profiling as follows:
<code display proglang=sh/ozc -px piggies.oz -o piggies.exe/
</p>
    </chapter>

    <chapter>
      <title/How To Invoke The Profiler/
      <p>The profiler interface is integrated in the Oz debugger
tool <code proglang=sh/ozd/ and can be invoked using the <code/-p/
option.  We can profile <q/The 3 Little Piggies/ as follows:
<code display proglang=sh/ozd -p piggies.exe -- --size 1000 --times 100/
Note how the double dash separates <code proglang=sh/ozd/'s arguments
from the application's arguments.  Shortly thereafter, the window
shown below pops up:
<picture.choice display>
	  <picture.extern to="prof1.gif" type="gif">
	</picture.choice>
Now click <em/Update/ and a summary of procedure calls is displayed.
We learn that the <code/SecondPiggy/ is called 100 times and the
<code/ThirdPiggy/ 10000 times (&ie; 100*100).
<picture.choice display>
	  <picture.extern to="prof2.gif" type="gif">
	</picture.choice>
The <code/FirstPiggy/ is not shown by default because it is called
only once.  Let's now select a different <em/Sort By/ (the menu button
on the right): we choose <em/heap/ to display the memory allocation
profile.  From this we verify &eg; that <code/ThirdPiggy/ allocates
about 100 times more memory as <code/SecondPiggy/, which is as it
should be since it is called 100 times more and allocates the same
large list.
<picture.choice display>
	  <picture.extern to="prof3.gif" type="gif">
	</picture.choice>
    </chapter>

    <chapter>
      <title/Command Line Options/
      <p>If you have created an Oz application which you normally start
from the shell as follows:
<code display/Foo ?{Args} ... /
Then you can run it under control of the Oz profiler by using the
following command instead:
<code display/ozd -p Foo -- ?{Args} .../
Any Oz application can be run in the profiler, but you only get the
full benefit of the profiling interface when the code being executed
was compiled with the <code/-p/ option to include profiling
instrumentation code.  The profiler and the debugger share the same
interface.</p>
      <p>The double dash <code/--/ separates the arguments intended for
<code/ozd/ from those intended for the application being run under the
profiler.
<list>
	  <entry/<code/--help/, <code/-h/, <code/-?//
	  <item/Display information on legal options, then exit/

	  <entry/<code/-p/, <code/--profiler/, <code/--mode=profiler//
	  <item/You must supply this option in order to start the profiler;
otherwise the debugger is started instead (see
<ptr.extern to="ozdoc:tools" key="chapter.debugger">)./

	  <entry/<code/-g/, <code/--debugger/, <code/--mode=debugger//
	  <item/This is the default option: it starts the debugger
(see <ptr.extern to="ozdoc:tools" key="chapter.debugger"
>). As mentioned above, in order to
actually start the profiler, you must supply the <code/-p/ option./

	  <entry/<code/-E/, <code/--(no)useemacs//
	  <item/Starts a subordinate Emacs process.  This will be used to
display the source code corresponding to the profile data being
examined./

	  <entry/<code/--emacs=?{FILE}//
	  <item/Specifies the Emacs binary to run for option <code/-E/.
The default is $<var env/OZEMACS/ if set, else <file/emacs/./
	</list></p>
    </chapter>

    <chapter>
      <title/Mixing Code With and Without Profiling Information/
      <p>
      If a procedure <<Foo>>, that has been compiled for profiling,
      calls another procedure <<Bar>>, that was not compiled for profiling,
      only the counters for <<Foo>> are incremented at
      runtime. So for example the heap memory allocated within <<Bar>> is
      added to the heap profile counter of <<Foo>>. For efficiency all
      the Oz library modules are compiled without profiling
      information. So if <<Foo>> itself does not much more than
      calling <<List.append>> it might show up high in the profilers
      window,  if it is often called with very long lists for
      example, whereas <<List.append>> will not show up at
      all. Nevertheless you might in this case consider changing the
      representation of your data structures.
    </chapter>
    <chapter>
      <title/How To Profile In The OPI/
<p>
      In the OPI the most convenient way to start the profiler is to
      choose the <code /Profiler/ item in the Oz menu of Emacs.
      This will open the profiler window and tell the compiler to
      instrument the code for profiling thereafter. So everything fed
      <em/after/ opening the profiler will be instrumented.
      Then press <code /reset/, run your application and press the
      <code/update/ button after its termination.
<p>
      Clicking on the bar of a particular procedure <<P>> in the
      profiler's window will try to locate the definition of <<P>> in
      an Emacs buffer.
<p>
      Profiling is switched off in the OPI by either closing the profiler
      window or by feeding
      <<<{Profiler.close}>>>
      which will close the profiler window and inform the compiler to
      generate uninstrumented code thereafter. Note that code
      previously compiled for profiling will still run slower, so you
      might consider recompilation.
    </chapter>
    <chapter>
      <title/The Profiler's User Interface/
<p>
     The profiler window consists of the following frames:
<list>
   <entry /<code>Procedures</code>/
     <item>Presents a list of bars for each procedure sorted by the
     sort criteria selected via the <code/Sort By/ menu. Clicking on a
     bar will update the <code/Proc Info/ frame and will additionally
     try to locate the definition of the corresponding procedure in an
     Emacs buffer.
     </item>
   <entry /<code>Proc Info</code>/ 
     <item>Lists for the selected procedure its name, the file name and
     line number of the source code of its definition plus the values
     of all the profile counters.
     </item>
   <entry /<code>Summary</code>/
     <item>Lists the sum of all the counters of all procedures being
     compiled for profiling.
     </item>
</list>
<p>
     The profiler provides the following buttons and menus:
<list>
   <entry /<code>Action</code>/
   <item>
     <list>
       <entry /<code>Update</code>/
       <item>Read the current values of the profile counters from the
       emulator and update the display in the <code>Procedures</code>
       frame. 
       </item>
       <entry /<code>Reset</code>/
       <item>Resets all profile counters to zero.</item>
     </list>
   <entry /<code>Options</code>/
   <item>
     <list>
       <entry /<code>Use Emacs</code>/
       <item>This is a toggle button that lets you choose whether 
       clicking on a bar in the <code/Procedures/ frame will tell
       Emacs to locate the definition of the selected procedure.
       </item>
       <entry /<code>Automatic Update</code>/
       <item>Lets the user select an interval in which the displays
       are updated periodically. By default automatic update is
       off.
       </item>
     </list>
   <entry /<code/update//  <item>Same as menu <code/Action --> Update/.</item>
   <entry /<code/reset//   <item>Same as menu <code/Action --> Reset/.</item>
   <entry /<code/Sort By// <item>Selects the sort criteria by which
   procedures are listed in the <code /Procedures/ frame.</item>
</list>
    </chapter>
</book>

<!--
Local Variables:
mode: sgml
mode: auto-fill
sgml-default-dtd-file: "book.ced"
sgml-auto-activate-dtd: t
adaptive-fill-mode: nil
End:
-->
