Top
Print

# The Mozart Profiler

## Denys Duchier, Benjamin Lorenz and Ralf Scheidhauer

> 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.

# 1 What Is Profiling

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.

The profiler collects information in a per procedure basis. This information consists of the following quantities:

heap

  Heap memory allocated by the procedure

calls

  How many times the procedure was called

samples

  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.

  This is broken and disabled in the current implementation!

closures

  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`.

# 2 How To Compile For Profiling

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 `--profiler` option. This option can also be abbreviated `-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.

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:

>     functor
>     import Application
>     define
>        Args = {Application.getCmdArgs
>                record(size( single type:int optional:false)
>                       times(single type:int optional:false))}
>        proc {FirstPiggy}
>           {List.make Args.size _}
>           {For 1 Args.times 1 SecondPiggy}
>        end
>        proc {SecondPiggy _}
>           {List.make Args.size _}
>           {For 1 Args.times 1 ThirdPiggy}
>        end
>        proc {ThirdPiggy _}
>           {List.make Args.size _}
>        end
>        {FirstPiggy}
>        {Application.exit 0}
>     end

The application can be compiled for profiling as follows:

> `ozc -px piggies.oz -o piggies.exe`

# 3 How To Invoke The Profiler

The profiler interface is integrated in the Oz debugger tool `ozd` and can be invoked using the `-p` option. We can profile ``The 3 Little Piggies'' as follows:

> `ozd -p piggies.exe -- --size 1000 --times 100`

Note how the double dash separates `ozd`'s arguments from the application's arguments. Shortly thereafter, the window shown below pops up:

Now click Update and a summary of procedure calls is displayed. We learn that the `SecondPiggy` is called 100 times and the `ThirdPiggy` 10000 times (i. e. 100*100).

The `FirstPiggy` is not shown by default because it is called only once. Let's now select a different Sort By (the menu button on the right): we choose heap to display the memory allocation profile. From this we verify e. g. that `ThirdPiggy` allocates about 100 times more memory as `SecondPiggy`, which is as it should be since it is called 100 times more and allocates the same large list.

# 4 Command Line Options

If you have created an Oz application which you normally start from the shell as follows:

> `Foo` Args`...`

Then you can run it under control of the Oz profiler by using the following command instead:

> `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 `-p` option to include profiling instrumentation code. The profiler and the debugger share the same interface.

The double dash `--` separates the arguments intended for `ozd` from those intended for the application being run under the profiler.

`--help`, `-h`, `-?`

  Display information on legal options, then exit

`-p`, `--profiler`, `--mode=profiler`

  You must supply this option in order to start the profiler; otherwise the debugger is started instead (see Chapter 4 of ``Oz Shell Utilities'').

`-g`, `--debugger`, `--mode=debugger`

  This is the default option: it starts the debugger (see Chapter 4 of ``Oz Shell Utilities''). As mentioned above, in order to actually start the profiler, you must supply the `-p` option.

`-E`, `--(no)useemacs`

  Starts a subordinate Emacs process. This will be used to display the source code corresponding to the profile data being examined.

`--emacs=`FILE

  Specifies the Emacs binary to run for option `-E`. The default is $`OZEMACS` if set, else `emacs`.

# 5 Mixing Code With and Without Profiling Information

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.

# 6 How To Profile In The OPI

In the OPI the most convenient way to start the profiler is to choose the `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 after opening the profiler will be instrumented. Then press `reset`, run your application and press the `update` button after its termination.

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.

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.

# 7 The Profiler's User Interface

The profiler window consists of the following frames:

`Procedures`

  Presents a list of bars for each procedure sorted by the sort criteria selected via the `Sort By` menu. Clicking on a bar will update the `Proc Info` frame and will additionally try to locate the definition of the corresponding procedure in an Emacs buffer.

`Proc Info`

  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.

`Summary`

  Lists the sum of all the counters of all procedures being compiled for profiling.

The profiler provides the following buttons and menus:

`Action`

  `Update`

    Read the current values of the profile counters from the emulator and update the display in the `Procedures` frame.

  `Reset`

    Resets all profile counters to zero.

`Options`

  `Use Emacs`

    This is a toggle button that lets you choose whether clicking on a bar in the `Procedures` frame will tell Emacs to locate the definition of the selected procedure.

  `Automatic Update`

    Lets the user select an interval in which the displays are updated periodically. By default automatic update is off.

`update`

  Same as menu `Action --> Update`.

`reset`

  Same as menu `Action --> Reset`.

`Sort By`

  Selects the sort criteria by which procedures are listed in the `Procedures` frame.

# Index

E | O

### E

environment variable
  `OZEMACS`: 4 Command Line Options

### O

`OZEMACS` environment variable: 4 Command Line Options