<?xml version="1.0" encoding="latin1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>
  <header>
    <copyright>
      <year>2007</year>
      <year>2011</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>
