Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > bd5c3d824c3db63ffd9226c15941e6ad > files > 1628

mozart-1.4.0-1mdv2010.0.i586.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>The Mozart Profiler</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><P class="margin"><A href="../index.html">Top</A><BR><A href="http://www.mozart-oz.org/download/view.cgi?action=print&class=tools&name=Profiler">Print</A></P><H1 align="center" class="title">The Mozart Profiler</H1><H2 align="center" class="authors"><A href="http://www.ps.uni-sb.de/~duchier/">Denys&nbsp;Duchier</A>, <A href="http://www.ps.uni-sb.de/~lorenz/">Benjamin&nbsp;Lorenz</A> and&nbsp;<A href="http://www.ps.uni-sb.de/~scheidhr/">Ralf&nbsp;Scheidhauer</A></H2><BLOCKQUOTE><P>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. </P></BLOCKQUOTE><HR><UL class="toc"><LI><A href="index.html#label1">1 What Is Profiling</A></LI><LI><A href="index.html#label2">2 How To Compile For Profiling</A></LI><LI><A href="index.html#label3">3 How To Invoke The Profiler</A></LI><LI><A href="index.html#label4">4 Command Line Options</A></LI><LI><A href="index.html#label7">5 Mixing Code With and Without Profiling Information</A></LI><LI><A href="index.html#label8">6 How To Profile In The OPI</A></LI><LI><A href="index.html#label9">7 The Profiler's User Interface</A></LI><LI><A href="index.html#label10">Index</A></LI></UL><HR><H1><A name="label1">1 What Is Profiling</A></H1><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: </P><DL><DT><EM>heap</EM></DT><DD><P>Heap memory allocated by the procedure </P></DD><DT><EM>calls</EM></DT><DD><P>How many times the procedure was called</P></DD><DT><EM>samples</EM></DT><DD><P>Statistical estimation of the time spent in the procedure. This works as follows: every 10ms a signal is delivered and the emulator increases the ``samples'' counter of the procedure currently executing. </P><DIV class="danger"><P class="margin"><IMG align="top" alt="Danger" src="danger.gif"></P><P> This is broken and disabled in the current implementation!</P></DIV></DD><DT><EM>closures</EM></DT><DD><P>How many times the corresponding closure was created. Note that nested procedure declarations like <CODE>Bar</CODE> in </P><BLOCKQUOTE class="code"><CODE><SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Foo</SPAN>&nbsp;X&nbsp;Y}<BR>&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Bar</SPAN>&nbsp;U&nbsp;V}&nbsp;<SPAN class="keyword">...</SPAN>&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;<SPAN class="keyword">...</SPAN>&nbsp;<BR><SPAN class="keyword">end</SPAN></CODE></BLOCKQUOTE><P> both consume runtime and memory since a new closure for <CODE>Bar</CODE> has to be created at runtime whenever <CODE>Foo</CODE> ist called. So one might consider lifting the definition of <CODE>Bar</CODE>. </P></DD></DL><P></P><H1><A name="label2">2 How To Compile For Profiling</A></H1><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>--profiler</CODE> option. This option can also be abbreviated <CODE>-p</CODE>. 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 ``The 3 Little Piggies'', and it does nothing but waste time and memory: </P><BLOCKQUOTE><PRE><SPAN class="keyword">functor</SPAN>&nbsp;<BR><SPAN class="keyword">import</SPAN>&nbsp;Application<BR><SPAN class="keyword">define</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Args&nbsp;=&nbsp;{Application<SPAN class="keyword">.</SPAN>getCmdArgs<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record(size(&nbsp;single&nbsp;type:int&nbsp;optional:<SPAN class="keyword">false</SPAN>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;times(single&nbsp;type:int&nbsp;optional:<SPAN class="keyword">false</SPAN>))}<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">FirstPiggy</SPAN>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{List<SPAN class="keyword">.</SPAN>make&nbsp;Args<SPAN class="keyword">.</SPAN>size&nbsp;_}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{For&nbsp;1&nbsp;Args<SPAN class="keyword">.</SPAN>times&nbsp;1&nbsp;SecondPiggy}<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">SecondPiggy</SPAN>&nbsp;_}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{List<SPAN class="keyword">.</SPAN>make&nbsp;Args<SPAN class="keyword">.</SPAN>size&nbsp;_}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{For&nbsp;1&nbsp;Args<SPAN class="keyword">.</SPAN>times&nbsp;1&nbsp;ThirdPiggy}<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">ThirdPiggy</SPAN>&nbsp;_}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{List<SPAN class="keyword">.</SPAN>make&nbsp;Args<SPAN class="keyword">.</SPAN>size&nbsp;_}<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;{FirstPiggy}<BR>&nbsp;&nbsp;&nbsp;{Application<SPAN class="keyword">.</SPAN>exit&nbsp;0}<BR><SPAN class="keyword">end</SPAN>&nbsp;<BR></PRE></BLOCKQUOTE><P> The application can be compiled for profiling as follows: </P><BLOCKQUOTE class="code"><CODE>ozc&nbsp;-px&nbsp;piggies.oz&nbsp;-o&nbsp;piggies.exe</CODE></BLOCKQUOTE><P></P><H1><A name="label3">3 How To Invoke The Profiler</A></H1><P>The profiler interface is integrated in the Oz debugger tool <CODE>ozd</CODE> and can be invoked using the <CODE><SPAN class="keyword">-</SPAN>p</CODE> option. We can profile ``The 3 Little Piggies'' as follows: </P><BLOCKQUOTE class="code"><CODE>ozd&nbsp;-p&nbsp;piggies.exe&nbsp;--&nbsp;--size&nbsp;1000&nbsp;--times&nbsp;100</CODE></BLOCKQUOTE><P> Note how the double dash separates <CODE>ozd</CODE>'s arguments from the application's arguments. Shortly thereafter, the window shown below pops up: </P><DIV align="center"><IMG alt="" src="prof1.gif"></DIV><P> Now click <EM>Update</EM> and a summary of procedure calls is displayed. We learn that the <CODE>SecondPiggy</CODE> is called 100 times and the <CODE>ThirdPiggy</CODE> 10000 times (i.&nbsp;e. 100*100). </P><DIV align="center"><IMG alt="" src="prof2.gif"></DIV><P> The <CODE>FirstPiggy</CODE> is not shown by default because it is called only once. Let's now select a different <EM>Sort By</EM> (the menu button on the right): we choose <EM>heap</EM> to display the memory allocation profile. From this we verify e.&nbsp;g. that <CODE>ThirdPiggy</CODE> allocates about 100 times more memory as <CODE>SecondPiggy</CODE>, which is as it should be since it is called 100 times more and allocates the same large list. </P><DIV align="center"><IMG alt="" src="prof3.gif"></DIV><P> </P><H1><A name="label4">4 Command Line Options</A></H1><P>If you have created an Oz application which you normally start from the shell as follows: </P><BLOCKQUOTE class="code"><CODE>Foo&nbsp;</CODE><I>Args</I><CODE>&nbsp;<SPAN class="keyword">...</SPAN>&nbsp;</CODE></BLOCKQUOTE><P> Then you can run it under control of the Oz profiler by using the following command instead: </P><BLOCKQUOTE class="code"><CODE>ozd&nbsp;<SPAN class="keyword">-</SPAN>p&nbsp;Foo&nbsp;<SPAN class="keyword">--</SPAN>&nbsp;</CODE><I>Args</I><CODE>&nbsp;<SPAN class="keyword">...</SPAN></CODE></BLOCKQUOTE><P> 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><SPAN class="keyword">-</SPAN>p</CODE> option to include profiling instrumentation code. The profiler and the debugger share the same interface.</P><P>The double dash <CODE><SPAN class="keyword">--</SPAN></CODE> separates the arguments intended for <CODE>ozd</CODE> from those intended for the application being run under the profiler. </P><DL><DT><CODE><SPAN class="keyword">--</SPAN>help</CODE>, <CODE><SPAN class="keyword">-</SPAN>h</CODE>, <CODE><SPAN class="keyword">-</SPAN>?</CODE></DT><DD><P>Display information on legal options, then exit</P></DD><DT><CODE><SPAN class="keyword">-</SPAN>p</CODE>, <CODE><SPAN class="keyword">--</SPAN>profiler</CODE>, <CODE><SPAN class="keyword">--</SPAN>mode=profiler</CODE></DT><DD><P>You must supply this option in order to start the profiler; otherwise the debugger is started instead (see <A href="../tools/node12.html#chapter.debugger">Chapter&nbsp;4 of ``Oz Shell Utilities''</A>).</P></DD><DT><CODE><SPAN class="keyword">-</SPAN>g</CODE>, <CODE><SPAN class="keyword">--</SPAN>debugger</CODE>, <CODE><SPAN class="keyword">--</SPAN>mode=debugger</CODE></DT><DD><P>This is the default option: it starts the debugger (see <A href="../tools/node12.html#chapter.debugger">Chapter&nbsp;4 of ``Oz Shell Utilities''</A>). As mentioned above, in order to actually start the profiler, you must supply the <CODE><SPAN class="keyword">-</SPAN>p</CODE> option.</P></DD><DT><CODE><SPAN class="keyword">-</SPAN>E</CODE>, <CODE><SPAN class="keyword">--</SPAN>(no)useemacs</CODE></DT><DD><P>Starts a subordinate Emacs process. This will be used to display the source code corresponding to the profile data being examined.</P></DD><DT><CODE><SPAN class="keyword">--</SPAN>emacs=</CODE><I>FILE</I></DT><DD><P>Specifies the Emacs binary to run for option <CODE><SPAN class="keyword">-</SPAN>E</CODE>. The default is $<A name="label5"></A><A name="label6"></A><CODE>OZEMACS</CODE> if set, else <CODE>emacs</CODE>.</P></DD></DL><P></P><H1><A name="label7">5 Mixing Code With and Without Profiling Information</A></H1><P> If a procedure <CODE>Foo</CODE>, that has been compiled for profiling, calls another procedure <CODE>Bar</CODE>, that was not compiled for profiling, only the counters for <CODE>Foo</CODE> are incremented at runtime. So for example the heap memory allocated within <CODE>Bar</CODE> is added to the heap profile counter of <CODE>Foo</CODE>. For efficiency all the Oz library modules are compiled without profiling information. So if <CODE>Foo</CODE> itself does not much more than calling <CODE>List<SPAN class="keyword">.</SPAN>append</CODE> it might show up high in the profilers window, if it is often called with very long lists for example, whereas <CODE>List<SPAN class="keyword">.</SPAN>append</CODE> will not show up at all. Nevertheless you might in this case consider changing the representation of your data structures. </P><H1><A name="label8">6 How To Profile In The OPI</A></H1><P> In the OPI the most convenient way to start the profiler is to choose the <CODE>Profiler</CODE> 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</EM> opening the profiler will be instrumented. Then press <CODE>reset</CODE>, run your application and press the <CODE>update</CODE> button after its termination.</P><P> Clicking on the bar of a particular procedure <CODE>P</CODE> in the profiler's window will try to locate the definition of <CODE>P</CODE> in an Emacs buffer.</P><P> Profiling is switched off in the OPI by either closing the profiler window or by feeding </P><BLOCKQUOTE class="code"><CODE>{Profiler<SPAN class="keyword">.</SPAN>close}</CODE></BLOCKQUOTE><P> 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. </P><H1><A name="label9">7 The Profiler's User Interface</A></H1><P> The profiler window consists of the following frames: </P><DL><DT><CODE>Procedures</CODE></DT><DD><P>Presents a list of bars for each procedure sorted by the sort criteria selected via the <CODE>Sort&nbsp;By</CODE> menu. Clicking on a bar will update the <CODE>Proc&nbsp;Info</CODE> frame and will additionally try to locate the definition of the corresponding procedure in an Emacs buffer. </P></DD><DT><CODE>Proc&nbsp;Info</CODE></DT><DD><P>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. </P></DD><DT><CODE>Summary</CODE></DT><DD><P>Lists the sum of all the counters of all procedures being compiled for profiling. </P></DD></DL><P></P><P> The profiler provides the following buttons and menus: </P><DL><DT><CODE>Action</CODE></DT><DD><P></P><DL><DT><CODE>Update</CODE></DT><DD><P>Read the current values of the profile counters from the emulator and update the display in the <CODE>Procedures</CODE> frame. </P></DD><DT><CODE>Reset</CODE></DT><DD><P>Resets all profile counters to zero.</P></DD></DL><P> </P></DD><DT><CODE>Options</CODE></DT><DD><P></P><DL><DT><CODE>Use&nbsp;Emacs</CODE></DT><DD><P>This is a toggle button that lets you choose whether clicking on a bar in the <CODE>Procedures</CODE> frame will tell Emacs to locate the definition of the selected procedure. </P></DD><DT><CODE>Automatic&nbsp;Update</CODE></DT><DD><P>Lets the user select an interval in which the displays are updated periodically. By default automatic update is off. </P></DD></DL><P> </P></DD><DT><CODE>update</CODE></DT><DD><P>Same as menu <CODE>Action&nbsp;<SPAN class="keyword">--&gt;</SPAN>&nbsp;Update</CODE>.</P></DD><DT><CODE>reset</CODE></DT><DD><P>Same as menu <CODE>Action&nbsp;<SPAN class="keyword">--&gt;</SPAN>&nbsp;Reset</CODE>.</P></DD><DT><CODE>Sort&nbsp;By</CODE></DT><DD><P>Selects the sort criteria by which procedures are listed in the <CODE>Procedures</CODE> frame.</P></DD></DL><P> </P><H1><A name="label10">Index</A></H1><CENTER><TABLE border="1" cellpadding="2"><TR><TD><A href="#_E">E</A></TD><TD><A href="#_O">O</A></TD></TR></TABLE></CENTER><H3 class="margin"><A name="_E">E</A></H3><DL><DT>environment variable</DT><DD><DL><DT><A><CODE>OZEMACS</CODE></A>: <A href="index.html#label5">4 Command Line Options</A></DT></DL></DD></DL><H3 class="margin"><A name="_O">O</A></H3><DL><DT><A><CODE>OZEMACS</CODE> environment variable</A>: <A href="index.html#label6">4 Command Line Options</A></DT></DL><HR><ADDRESS><A href="http://www.ps.uni-sb.de/~duchier/">Denys&nbsp;Duchier</A>, <A href="http://www.ps.uni-sb.de/~lorenz/">Benjamin&nbsp;Lorenz</A> and&nbsp;<A href="http://www.ps.uni-sb.de/~scheidhr/">Ralf&nbsp;Scheidhauer</A><BR><SPAN class="version">Version 1.4.0 (20090610)</SPAN></ADDRESS></BODY></HTML>