164 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			164 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| 
								 | 
							
								<!doctype html public "-//W3C//DTD HTML 4.01//EN"
							 | 
						||
| 
								 | 
							
									"http://www.w3.org/TR/html4/strict.dtd">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<html>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<head>
							 | 
						||
| 
								 | 
							
								    <title>Profiling programs</title>
							 | 
						||
| 
								 | 
							
								    <link rel=stylesheet  href="../styles.css" type="text/css">
							 | 
						||
| 
								 | 
							
								</head>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<body>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<hr />
							 | 
						||
| 
								 | 
							
								<h1><a class="back" title="Return to index" href="index.html#profiling">Profiling programs</a></h1>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								In this example, we will illustrate the use of:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<ul>
							 | 
						||
| 
								 | 
							
									<li>events</li>
							 | 
						||
| 
								 | 
							
									<li>monitors</li>
							 | 
						||
| 
								 | 
							
								</ul>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								by defining a simple profiler that prints the starting and ending time for processing a message sent to an object.
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<hr />
							 | 
						||
| 
								 | 
							
								<h2><a class="back" title="Return to index" name="events" href="index.html#profiling_events">Messages as events</a></h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								In a pure object-oriented system, all computations start by sending messages to objects. We can thus define an <em>event</em> as the sending of a message to an object. An event can then be specified by the tuple <code>(Object, Message, Sender)</code>. This definition can be refined by interpreting the sending of a message and the return of the control to the object that has sent the message as two distinct events. We call these events respectively <code>before</code> and <code>after</code>. Therefore, we end up by representing an event by the tuple <code>(Event, Object, Message, Sender)</code>. For instance, if we send the message:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    | ?- foo::bar(X).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    X = 1
							 | 
						||
| 
								 | 
							
								    yes
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								the two corresponding events will be:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    (before, foo, bar(X), user)
							 | 
						||
| 
								 | 
							
								    (after, foo, bar(1), user)
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								Note that the second event is only generated if the message succeeds. If the message as a goal have multiple solutions, then one <code>after</code> event will be generated for each solution.
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								Events are automatically generated by the message sending mechanisms for each public message sent using the <a title="Consult reference manual" href="../refman/control/to_object2.html"><code>::/2</code></a> operator.
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<hr />
							 | 
						||
| 
								 | 
							
								<h2><a class="back" title="Return to index" name="monitors" href="index.html#profiling_monitors">Profilers as monitors</a></h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								A monitor is an object that reacts whenever a spied event occurs. The monitor actions are defined by two event handlers: <a title="Consult reference manual" href="../refman/methods/before3.html"><code>before/3</code></a> for <code>before</code> events and <a title="Consult reference manual" href="../refman/methods/after3.html"><code>after/3</code></a> for <code>after</code> events. These predicates are automatically called by the message sending mechanisms when an event registered for the monitor occurs.
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								In our example, we need a way to get the current time before and after we process a message. We will assume that we have a <code>time</code> object implementing a <code>cpu_time/1</code> predicate that returns the current CPU time for the Prolog session:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    :- object(time).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :- public(cpu_time/1).
							 | 
						||
| 
								 | 
							
								        :- mode(cpu_time(-number), one).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ...
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :- end_object.
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								Our profiler will be named <code>stop_watch</code>. It must define event handlers for the <code>before</code> and <code>after</code> events that will print the event description (object, message, and sender) and the current time:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    :- object(stop_watch).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :- uses(time).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        before(Object, Message, Sender) :-
							 | 
						||
| 
								 | 
							
								            write(Object), write(' <-- '), writeq(Message),
							 | 
						||
| 
								 | 
							
								            write(' from '), write(Sender), nl, write('STARTING at '),
							 | 
						||
| 
								 | 
							
								            time::cpu_time(Seconds), write(Seconds), write(' seconds'), nl.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        after(Object, Message, Sender) :-
							 | 
						||
| 
								 | 
							
								            write(Object), write(' <-- '), writeq(Message),
							 | 
						||
| 
								 | 
							
								            write(' from '), write(Sender), nl, write('ENDING at '),
							 | 
						||
| 
								 | 
							
								            time::cpu_time(Seconds), write(Seconds), write(' seconds'), nl.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :- end_object.
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								After compiling and loading the <code>stop_watch</code> object (and the objects that we want to profile), we can use the <a title="Consult reference manual" href="../refman/builtins/define_events5.html"><code>define_events/5</code></a> built-in predicate to set up our profiler. For example, to profile all messages that are sent to the object <code>foo</code>, we need to call the goal:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    | ?- define_events(_, foo, _, _, stop_watch).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    yes
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								This call will register <code>stop_watch</code> as a monitor to all messages sent to object <code>foo</code>, for both <code>before</code> and <code>after</code> events. Note that we say "as a monitor", not "the monitor": we can have any number of monitors over the same events.
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								From now on, every time we sent a message to <code>foo</code>, the <code>stop_watch</code> monitor will print the starting and ending times for the message execution. For instance:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    | ?- foo::bar(X).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    foo <-- bar(X) from user
							 | 
						||
| 
								 | 
							
								    STARTING at 12.87415 seconds
							 | 
						||
| 
								 | 
							
								    foo <-- bar(1) from user
							 | 
						||
| 
								 | 
							
								    ENDING at 12.87419 seconds
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    X = 1
							 | 
						||
| 
								 | 
							
								    yes
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								To stop profiling the messages sent to <code>foo</code> we use the <a title="Consult reference manual" href="../refman/builtins/abolish_events5.html"><code>abolish_events/5</code></a>
							 | 
						||
| 
								 | 
							
								built-in predicate:
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<pre>
							 | 
						||
| 
								 | 
							
								    | ?- abolish_events(_, foo, _, _, stop_watch).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    yes
							 | 
						||
| 
								 | 
							
								</pre>
							 | 
						||
| 
								 | 
							
								<p>
							 | 
						||
| 
								 | 
							
								This call will abolish all events defined over the object <code>foo</code> assigned to the <code>stop_watch</code> monitor.
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<hr />
							 | 
						||
| 
								 | 
							
								<h2><a class="back" title="Return to index" name="summary" href="index.html#profiling_summary">Summary</a></h2>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<ul>
							 | 
						||
| 
								 | 
							
								    <li>An event is defined as the sending of a (public) message to an object.</li>
							 | 
						||
| 
								 | 
							
								</ul>
							 | 
						||
| 
								 | 
							
								<ul>
							 | 
						||
| 
								 | 
							
								    <li>There are two kinds of events: <code>before</code> events, generated before a message is processed, and <code>after</code> events, generated after the message processing completed successfully.</li>
							 | 
						||
| 
								 | 
							
								</ul>
							 | 
						||
| 
								 | 
							
								<ul>
							 | 
						||
| 
								 | 
							
								    <li>Any object can be declared as a monitor to any event.</li>
							 | 
						||
| 
								 | 
							
								</ul>
							 | 
						||
| 
								 | 
							
								<ul>
							 | 
						||
| 
								 | 
							
								    <li>A monitor defines event handlers, the predicates <a title="Consult reference manual" href="../refman/methods/before3.html"><code>before/3</code></a> and <a title="Consult reference manual" href="../refman/methods/after3.html"><code>after/3</code></a>, that are automatically called by the runtime engine when a spied event occurs.</li>
							 | 
						||
| 
								 | 
							
								</ul>
							 | 
						||
| 
								 | 
							
								<ul>
							 | 
						||
| 
								 | 
							
								    <li>Three built-in predicates, <a title="Consult reference manual" href="../refman/builtins/define_events5.html"><code>define_events/5</code></a>, <a title="Consult reference manual" href="../refman/builtins/current_event5.html"><code>current_event/5</code></a>, and <a title="Consult reference manual" href="../refman/builtins/abolish_events5.html"><code>abolish_events/5</code></a>, enables us define, query, and abolish both events and monitors.</li>
							 | 
						||
| 
								 | 
							
								</ul>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<hr />
							 | 
						||
| 
								 | 
							
								<p class="center">
							 | 
						||
| 
								 | 
							
								<strong><a href="reflection.html">Previous</a> | <a href="index.html">Next</a> | <a href="index.html">Table of Contents</a> | <a href="../bibliography.html">Bibliography</a> | <a href="../glossary.html">Glossary</a></strong>
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<p class="center">
							 | 
						||
| 
								 | 
							
								Last updated on: July 4, 2000
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								<hr />
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</body>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</html>
							 |