<?xml version="1.0" encoding="latin1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2007</year>
<year>2007</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>Percept</title>
<prepared>Bj�rn-Egil Dahlberg</prepared>
<docno></docno>
<date>2007-11-02</date>
<rev>A</rev>
<file>percept_ug.xml</file>
</header>
<p>
Percept, or Percept - Erlang Concurrency Profiling Tool, utilizes trace
informations and profiler events to form a picture of the processes's and
ports runnability.
</p>
<section>
<title>Introduction</title>
<p>
Percept uses <c>erlang:trace/3</c> and <c>erlang:system_profile/2</c> to monitor events from
process states. Such states are,</p>
<list>
<item>waiting</item>
<item>running</item>
<item>runnable</item>
<item>free</item>
<item>exiting</item>
</list>
<p>
There are some other states too, <c>suspended</c>, <c>hibernating</c>, and
garbage collecting (<c>gc</c>). The only ignored state is <c>gc</c> and a process is considered to have
its previous state through out the entire garbage collecting phase. The main reason for this, is that our
model considers the <c>gc</c> as a third state neither active nor inactive.
</p>
<p>
A waiting or suspended process is considered an inactive process and a running or
runnable process is considered an active process.
</p>
<p>
Events are collected and stored to a file. The file can be moved and
analyzed on a different machine than the target machine.
</p>
<p>
Note, even if percept is not installed on your target machine, profiling
can still be done via the module <seealso marker="percept_profile">percept_profile</seealso>
located in runtime_tools.
</p>
</section>
<section>
<title>Getting started</title>
<section>
<title>Profiling</title>
<p>
There are a few ways to start the profiling of a specific code. The
command <c>percept:profile/3</c> is a preferred way.
</p>
<p>
The command takes a filename for the data destination file as first
argument, a callback entry-point as second argument and a
list of specific profiler options, for instance <c>procs</c>, as third
argument.
</p>
<p>
Let's say we have a module called example that initializes our
profiling-test and let it run under some defined manner designed by ourself.
The module needs a start function, let's call it go and it takes zero arguments.
The start arguments would look like:
</p>
<p><c>percept:profile("test.dat", {test, go, []}, [procs]).</c></p>
<p>
For a semi-real example we start a tree of processes that does sorting
of random numbers. In our model below we use a controller process that
distributes work to different client processes.
</p>
<codeinclude file="sorter.erl" tag="" type="none"></codeinclude>
<p>We can now start our test using percept:</p>
<pre>
Erlang (BEAM) emulator version 5.6 [async-threads:0] [kernel-poll:false]
Eshell V5.6 (abort with ^G)
1> percept:profile("test.dat", {sorter, go, [5, 2000, 15]}, [procs]).
Starting profiling.
ok
</pre>
<p>
Percept sets up the trace and profiling facilities to listen for process
specific events. It then stores these events to the <c>test.dat</c>
file. The profiling will go on for the whole duration until
<c>sorter:go/3</c> returns and the profiling has concluded.
</p>
</section>
<section>
<title>Data viewing</title>
<p>
To analyze this file, use <c>percept:analyze("test.dat")</c>. We can do
this on any machine with Percept installed. The command will parse the
data file and insert all events in a RAM database, <c>percept_db</c>. The
initial command will only prompt how many processes were involved in the
profile.
</p>
<pre>
2> percept:analyze("test.dat").
Parsing: "test.dat"
Parsed 428 entries in 3.81310e-2 s.
17 created processes.
0 opened ports.
ok
</pre>
<p>
To view the data we start the web-server using
<c>percept:start_webserver/1</c>. The command will return the hostname
and the a port where we should direct our favorite web browser.
</p>
<pre>
3> percept:start_webserver(8888).
{started,"durin",8888}
4>
</pre>
<section>
<title>Overview selection</title>
<p>
Now we can view our data. The database has its content from
<c>percept:analyze/1</c> command and the webserver is started.
</p>
<p>
When we click on the <c>overview</c> button in the menu percept will
generate a graph of the concurrency and send it to our web browser. In this
view we get no details but rather the big picture. We can see if
our processes behave in an inefficient manner. Dips in the graph represents
low concurrency in the erlang system.
</p>
<p>
We can zoom in on different areas of the graph either using the mouse
to select an area or by specifying min and max ranges in the edit boxes.
</p>
<note>
<p>Measured time is presented in seconds if nothing else is stated.</p>
</note>
<image file="percept_overview.gif">
<icaption>Overview selection</icaption>
</image>
</section>
<section>
<title>Processes selection</title>
<p>
To get a more detailed description we can select the process view by
clicking the <c>processes</c> button in the menu.
</p>
<p>
The table shows process id's that are click-able and direct you to
the process information page, a lifetime bar that presents a rough estimate
in green color about when the process was alive during profiling, an
entry-point, its registered name if it had one and the process's
parent id.
</p>
<p>
We can select which processes we want to compare and then hit the
<c>compare</c> button on the top right of the screen.
</p>
<image file="percept_processes.gif">
<icaption>Processes selection</icaption>
</image>
</section>
<section>
<title>Compare selection</title>
<p>
The activity bar under the concurrency graph shows each process's
runnability. The color green shows when a process is active (which is
running or runnable) and the white color represents time when a
process is inactive (waiting in a receive or is suspended).
</p>
<p>
To inspect a certain process click on the process id button, this will
direct you to a process information page for that specific process.
</p>
<image file="percept_compare.gif">
<icaption>Processes compare selection</icaption>
</image>
</section>
<section>
<title>Process information selection</title>
<p>
Here we can some general information for the process. Parent and
children processes, spawn and exit times, entry-point and start arguments.
</p>
<p>
We can also see the process' inactive times. How many times it has
been waiting, statistical information and most importantly in which
function.
</p>
<p>
The time percentages presented in process information are of time spent in waiting, not total run time.
</p>
<image file="percept_processinfo.gif">
<icaption>Process information selection</icaption>
</image>
</section>
</section>
</section>
</chapter>