Sophie

Sophie

distrib > Fedora > 17 > i386 > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 1184

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- Percept</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/percept-0.8.7.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>Percept</strong><br><strong>User's Guide</strong><br><small>Version 0.8.7</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="loadscrollpos" title="Percept" expanded="true">Percept<ul>
<li><a href="percept_ug.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="percept_ug.html#id57231">Introduction</a></li>
<li title="Getting started"><a href="percept_ug.html#id61101">Getting started</a></li>
</ul>
</li>
<li id="no" title="egd" expanded="false">egd<ul>
<li><a href="egd_ug.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="egd_ug.html#id61190">Introduction</a></li>
<li title="File example"><a href="egd_ug.html#id61212">File example</a></li>
<li title="ESI example"><a href="egd_ug.html#id62010">ESI example</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>1 Percept</h1>
  
    <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>

  <h3><a name="id57231">1.1 
        Introduction</a></h3>
    
    <p>
	Percept uses <span class="code">erlang:trace/3</span> and <span class="code">erlang:system_profile/2</span> to monitor events from 
	process states. Such states are,</p>
	<ul>
	  <li>waiting</li> 
	  <li>running</li>
	  <li>runnable</li>
	  <li>free</li>
	  <li>exiting</li>
	</ul>
    <p>
	There are some other states too, <span class="code">suspended</span>, <span class="code">hibernating</span>, and 
	garbage collecting (<span class="code">gc</span>). The only ignored state is <span class="code">gc</span> 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 <span class="code">gc</span> 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 <span class="bold_code"><a href="percept_profile.html">percept_profile</a></span>
	located in runtime_tools.
    </p>
  
  <h3><a name="id61101">1.2 
        Getting started</a></h3>
    
    <h4>Profiling</h4>
      
    <p>
	There are a few ways to start the profiling of a specific code. The
	command <span class="code">percept:profile/3</span> 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 <span class="code">procs</span>, 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><span class="code">percept:profile("test.dat", {test, go, []}, [procs]).</span></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>
<div class="example"><pre>

-module(sorter).
-export([go/3,loop/0,main/4]).

go(I,N,M) -&gt;
    spawn(?MODULE, main, [I,N,M,self()]),
    receive done -&gt; ok end.

main(I,N,M,Parent) -&gt;
    Pids = lists:foldl(
	fun(_,Ps) -&gt; 
	    [ spawn(?MODULE,loop, []) | Ps]
	end, [], lists:seq(1,M)),

    lists:foreach(
	fun(_) -&gt; 
	    send_work(N,Pids),
	    gather(Pids)
	end, lists:seq(1,I)),

    lists:foreach(
	fun(Pid) -&gt;
	    Pid ! {self(), quit}
	end, Pids),

    gather(Pids), Parent ! done.

send_work(_,[]) -&gt; ok;
send_work(N,[Pid|Pids]) -&gt;
    Pid ! {self(),sort,N},
    send_work(round(N*1.2),Pids).

loop() -&gt;
    receive
	{Pid, sort, N} -&gt; dummy_sort(N),Pid ! {self(), done},loop();
	{Pid, quit} -&gt; Pid ! {self(), done}
    end.
	    
dummy_sort(N) -&gt; lists:sort([ random:uniform(N) || _ &lt;- lists:seq(1,N)]).

gather([]) -&gt; ok;
gather([Pid|Pids]) -&gt; receive {Pid, done} -&gt; gather(Pids) end.
</pre></div>    <p>We can now start our test using percept:</p>
    <div class="example"><pre>
Erlang (BEAM) emulator version 5.6 [async-threads:0] [kernel-poll:false]

Eshell V5.6  (abort with ^G)
1&gt; percept:profile("test.dat", {sorter, go, [5, 2000, 15]}, [procs]).
Starting profiling.
ok
    </pre></div>
    <p>
	Percept sets up the trace and profiling facilities to listen for process
	specific events. It then stores these events to the <span class="code">test.dat</span>
	file. The profiling will go on for the whole duration until
	<span class="code">sorter:go/3</span> returns and the profiling has concluded.
     </p>
     
     <h4>Data viewing</h4>
      
     <p>
	To analyze this file, use <span class="code">percept:analyze("test.dat")</span>. 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, <span class="code">percept_db</span>. The
	initial command will only prompt how many processes were involved in the
	profile.
     </p>
     <div class="example"><pre>
2&gt; percept:analyze("test.dat").                                      
Parsing: "test.dat" 
Parsed 428 entries in 3.81310e-2 s.
    17 created processes.
    0 opened ports.
ok
     </pre></div>
     <p>
	To view the data we start the web-server using
	<span class="code">percept:start_webserver/1</span>. The command will return the hostname
	and the a port where we should direct our favorite web browser.
     </p>
     <div class="example"><pre>
3&gt; percept:start_webserver(8888).
{started,"durin",8888}
4&gt; 
     </pre></div>
     <h4>Overview selection</h4>
       
     <p>
	Now we can view our data. The database has its content from
	<span class="code">percept:analyze/1</span> command and the webserver is started.
     </p>
     <p>
	When we click on the <span class="code">overview</span> 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>
    <div class="note">
<div class="label">Note</div>
<div class="content"><p>
        <p>Measured time is presented in seconds if nothing else is stated.</p>
    </p></div>
</div>
    <img alt="IMAGE MISSING" src="percept_overview.gif"><br>
      <em>Figure
        1.1:
         
        Overview selection</em>
    
    
    <h4>Processes selection</h4>
       
    <p>
	To get a more detailed description we can select the process view by
	clicking the <span class="code">processes</span> 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
	<span class="code">compare</span> button on the top right of the screen.
    </p>
    <img alt="IMAGE MISSING" src="percept_processes.gif"><br>
      <em>Figure
        1.2:
         
        Processes selection</em>
    
    
    <h4>Compare selection</h4>
       
    <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>
    <img alt="IMAGE MISSING" src="percept_compare.gif"><br>
      <em>Figure
        1.3:
         
        Processes compare selection</em>
    
    
    <h4>Process information selection</h4>
       
    <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>
    <img alt="IMAGE MISSING" src="percept_processinfo.gif"><br>
      <em>Figure
        1.4:
         
        Process information selection</em>
    
    
    
  
</div>
<div class="footer">
<hr>
<p>Copyright © 2007-2012 Ericsson AB, All Rights Reserved</p>
</div>
</div>
</div></body>
</html>