[Openmcl-cvs-notifications] r9193 - in /trunk/source/library: chud-metering.lisp chud-metering.txt

gb at clozure.com gb at clozure.com
Sat Apr 19 00:07:05 EDT 2008


Author: gb
Date: Sat Apr 19 00:07:04 2008
New Revision: 9193

Log:
Update.

Modified:
    trunk/source/library/chud-metering.lisp
    trunk/source/library/chud-metering.txt

Modified: trunk/source/library/chud-metering.lisp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/library/chud-metering.lisp (original)
+++ trunk/source/library/chud-metering.lisp Sat Apr 19 00:07:04 2008
@@ -1,6 +1,6 @@
 ;;;-*-Mode: LISP; Package: (CHUD (:USE CL CCL)) -*-
 ;;;
-;;;   Copyright (C) 2005 Clozure Associates and contributors
+;;;   Copyright (C) 2005,2008 Clozure Associates and contributors
 ;;;   This file is part of OpenMCL.  =

 ;;;
 ;;;   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
@@ -24,8 +24,7 @@
 =

 (defpackage "CHUD"
   (:use "CL" "CCL")
-  (:export "METER" "PREPARE-METERING" "SHARK-SESSION-PATH"
-           "LAUNCH-SHARK" "CLEANUP-SPATCH-FILES" "RESET-METERING"))
+  (:export "METER" "*SHARK-CONFIG-FILE*"))
   =

 (in-package "CHUD")
 =

@@ -75,8 +74,10 @@
 =

   =

 =

-(defvar *shark-process* nil)
-(defvar *sampling* nil)
+(defloadvar *shark-process* nil)
+(defloadvar *sampling* nil)
+
+(defloadvar *debug-shark-process-output* nil)
 =

 =

 (defun safe-shark-function-name (function)
@@ -120,6 +121,7 @@
 =

 #+x8664-target
 (defun identify-functions-with-pure-code ()
+  (ccl::freeze)
   (ccl::collect ((functions))
     (block walk
       (let* ((frozen-dnodes (ccl::frozen-space-dnodes)))
@@ -135,6 +137,7 @@
 =

 #+ppc-target
 (defun identify-functions-with-pure-code ()
+  (ccl:purify)
   (multiple-value-bind (pure-low pure-high)
                                  =

       (ccl::do-gc-areas (a)
@@ -170,9 +173,9 @@
                        (ccl::%address-of  (uvref y 0))))))))))
         =

                            =

+
+
 (defun generate-shark-spatch-file ()
-  #+ppc-target (ccl::purify)
-  #+x86-target (ccl::freeze)
   (let* ((functions (identify-functions-with-pure-code)))
     (with-open-file (f (make-pathname
                         :host nil
@@ -230,7 +233,8 @@
       (let* ((output (external-process-output-stream *shark-process*)))
 	(do* ((line (read-line output nil nil) (read-line output nil nil)))
 	     ((null line))
-          (format t "~&~a" line)
+	  (when *debug-shark-process-output*
+	    (format t "~&~a" line))
 	  (when (search "ready." line :key #'char-downcase)
             (sleep 1)
 	    (return)))))))
@@ -246,14 +250,15 @@
       (let* ((out (ccl::external-process-output p)))
 	(do* ((line (read-line out nil nil) (read-line out nil nil)))
 	     ((null line))
-          (format t "~&~a" line)
+	  (when *debug-shark-process-output*
+	    (format t "~&~a" line))
 	  (when (search "Created session file:" line)
 	    (display-shark-session-file line)
 	    (return))))))
 =

 =

 =

-(defmacro meter (form &key reset)
+(defmacro meter (form &key reset debug-output)
   (let* ((hook (gensym))
 	 (block (gensym))
 	 (process (gensym)))
@@ -263,14 +268,16 @@
 			 (eq (external-process-status p) :signaled))
 		 (setq *shark-process* nil
 		       *sampling* nil))))
-      (ensure-shark-process ,reset #',hook)
-      (unwind-protect
-         (progn
-           (enable-sampling)
-           ,form)
-        (disable-sampling)
-	(let* ((,process *shark-process*))
-	  (when ,process
-	    (scan-shark-process-output ,process))))))))
-
-
+	(let* ((*debug-shark-process-output* ,debug-output))
+	  (ensure-shark-process ,reset #',hook)
+	  (unwind-protect
+	       (progn
+		 (enable-sampling)
+		 ,form)
+	    (disable-sampling)
+	    (let* ((,process *shark-process*))
+	      (when ,process
+		(scan-shark-process-output ,process)))))))))
+
+;;; Try to clean up after ourselves when the lisp quits.
+(pushnew 'terminate-shark-process ccl::*save-exit-functions*)

Modified: trunk/source/library/chud-metering.txt
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/library/chud-metering.txt (original)
+++ trunk/source/library/chud-metering.txt Sat Apr 19 00:07:04 2008
@@ -1,182 +1,156 @@
-Using Apple's CHUD metering tools from OpenMCL
+Using Apple's CHUD metering tools from CCL
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 =

- Prerequisites
+Prerequisites
+-------------
 =

 Apple's CHUD metering tools are available (as of this writing) from:
 =

 <ftp://ftp.apple.com/developer/Tool_Chest/Testing_-_Debugging/Performance_=
tools/>. =

 =

-There are also some CHUD packages distributed with some recent
-versions of Xcode; the standalone versions available via FTP seem to
-work much better with the OpenMCL interface. Both versions 4.1.1 and
-4.2.2 of the CHUD tools seem to work reasonably well; earlier versions
-provide a different ABI, and it's not known whether any future
-versions will be compatible.
+The CHUD tools are also generally bundled with Apple's XCode tools.
+CBUD 4.5.0 (which seems to be bundled with XCode 3.0) seems to work
+well with this interface; later versions may have problems.
+Versions of CHUD as old as 4.1.1 may work with 32-bit PPC versions
+of CCL; later versions (not sure exactly -what- versions) added
+x86, ppc64, and x86-64 support.
 =

-There don't seem to be any versions of CHUD that can deal with 64-bit
-processes.
+One way to tell whether any version of the CHUD tools is installed
+is to try to invoke the "shark" command-line program (/usr/bin/shark)
+from the shell:
 =

-Ensure that either version 4.1.1 or 4.2.2 of the CHUD tools are
-installed. One side-effect of installation is that the folder "
-/Developer/Applications/Performance Tools" will have been created and
-will contain an application called "Shark". Double-click on Shark; in
-its "Preferences" window's "Search Paths" pane, use the "+" button to
-add your home directory to the "Patch Files" search path.
+shell> shark --help
 =

- Background
+and verifying that that prints a usage summary.
 =

-CHUD's Shark application is a user interface to its low-level
-performance monitoring facilities; those facilities provide access to
-high-resolution timers, on-chip debugging information, and OS
-performance counters. Shark allows the user to run sampling sessions,
-which record information about the context in which sampling events
-(such as timer interrupts) occur; at the end of the session, Shark
-processes the sampled data and presents a browsable interface which
-shows the processes, threads, and functions associated with those
-events.
+CHUD consists of several components, including command-line programs,
+GUI applications, kernel extensions, and "frameworks" (collections of
+libraries, headers, and other resources which applications can use to
+access functionality provided by the other components.)  Past versions
+of CCL/OpenMCL have used the CHUD framework libraries to control the
+CHUD profiler.  Even though the rest of CHUD is currently 64-bit aware,
+the frameworks are unfortunately still only available as 32-bit libraries,
+so the traditional way of controlling the profiling facility from OpenMCL
+has only worked from DarwinPPC32 versions.
 =

-For many processes, Shark can identify functions (the range of
-addresses corresponding to the address of the first and last
-instructions in the function) by interpreting symbolic information
-contained in the executable file. This strategy enables it to identify
-C and assembler functions in OpenMCL's lisp kernel, but doesn't help
-much in identifying Lisp functions. Fortunately, Shark does have the
-ability to read "patch files" , which associate symbolic names to
-regions of a process's address space), and fortunately OpenMCL can be
-told to move the machine code (the "code vector") associated with a
-compiled function to a static memory area (so that the addresses of
-the first and last instructions in a compiled lisp function remain
-constant); it's possible to assign fixed addresses to the code vectors
-of all functions in the lisp at a given time, and to give symbolic
-names to the memory regions that delimit those code vectors.
+Two of the CHUD component programs are of particular interest:
 =

-The process of moving code vectors to a static (and incidentally
-read-only) memory area is sometimes referred to as "purification".
+1) The "Shark" application (often installed in
+"/Developer/Applications/Performance Tools/Shark.app"), which provides
+a graphical user interface for exploring and analyzing profiling results
+and provides tools for creating "sampling configurations" (see below),
+among other things.
 =

- A Sampling Sample
+2) the "shark" program ("/usr/bin/shark"), which can be used to control
+the CHUD profiling facility and to collect sampling data, which can then
+be displayed and analyzed in Shark.app.
 =

-There's a little bit of flexibility in the order in which these steps
-are performed, but for the sake of argument we'll pretend here that
-there isn't.
+The fact that these two (substantially different) programs have names that
+differ only in alphabetic case may be confusing.  The discussion below
+tries to consistently distinguish between "the shark program" and "the
+Shark application".
 =

-1) Run Shark, and put it in "remote" mode.
+Usage synopsis
+--------------
 =

-Run Shark. Ensure that it's in "Programmatic (Remote)" mode by
-selecting that option from the "Sampling" menu, or by pressing the key
-equivalent "command-shift-R". In the main Shark window, ensure that
-the sampling type is set to "Time Profile", select "Process" (instead
-of "Everything" ) from the next popup, and doing so should cause the
-third popup to select "Remote Client".
+? (defun fact (n) (if (zerop n) 1 (* n (fact (1- n)))))
+FACT
+? (require "CHUD-METERING")
+"CHUD-METERING"
+("CHUD-METERING")
+? (chud:meter (null (fact 10000)))
+NIL	      ; since that large number is not NULL
 =

-2) Meter some code in OpenMCL.
+and, a few seconds after the result is returned, a file whose
+name is of the form "session_nnn.mshark" will open in Shark.app.
 =

-In OpenMCL, do:
+The fist time that CHUD:METER is used in a lisp session, it'll do a
+few things to prepare subsequent profiling sessions.  Those things
+include:
 =

-? (require "CHUD-METERING")
+1) creating a directory to store files that are related to using
+the CHUD tools in this lisp session.  This directory is created in
+the user's home directory and has a name of the form:
 =

-and ensure that the code that you want to profile is defined.
+profiling-session-<lisp-kernel>-<pid>_<mm>-<dd>-<yyyy>_<h>.<m>.<s>
 =

-? (defun fact (n)
-    (if (zerop n)
-      1
-      (* n (fact (1- n)))))
-FACT
-? (defun fact-n-m-times (m n)
-    (dotimes (i m)
-      (fact n)))
-FACT-N-M-TIMES
+where <pid> is the lisp's process id, <lisp-kernel> is the name of
+the lisp kernel (of all things ...), and the other values provide
+a timestamp.
 =

-Then run something with metering enabled:
+2) does whatever needs to be done to ensure that currently-defined
+lisp functions don't move around as the result of GC activity, then
+writes a text file describing the names and addresses of those functions
+to the profiling-session directory created above.  (The naming conventions
+for and format of that file are described in
 =

-? (CHUD:METER (fact-n-m-times 1000 1000))
+<http://developer.apple.com/documentation/DeveloperTools/Conceptual/SharkU=
serGuide/MiscellaneousTopics/chapter_951_section_4.html#//apple_ref/doc/uid=
/TP40005233-CH14-DontLinkElementID_42>
 =

-The first time that CHUD:METER is invoked in a lisp session, it'll:
+3) run the shark program ("/usr/bin/shark") and wait until it's ready to
+receive signals that control its operation.
 =

-1. Ensure that Shark is running
+This startup activity typically takes a few seconds; after it's been
+completed, subsequent use of CHUD:METER doesn't involve that overhead.
+(See the discussion of :RESET below.)
 =

-2. Move the code vectors of all functions to a static =

-   memory area.
+After any startup activity is complete, CHUD:METER arranges to send
+a "start profiling" signal to the running shark program, executes
+the form, sends a "stop profiling" signal to the shark program, and
+reads its diagnostic output, looking for the name of the ".mshark"
+file it produces.  If it's able to find this filename, it arranges
+for "Shark.app" to open it
 =

-3. Write a Shark "spatch" file to the user's home =

-   directory (which is where we configure Shark to look =

-   for such files back in the "Prerequisites" section.)
-   See also CHUD:*SPATCH-DIRECTORY-PATH*.
+Profiling "configurations".
+--------------------------
 =

-4. Try to ensure that Shark is running in "remote" mode. =

-   (I don't know of any way in which this can be ensured =

-   programatically, so it'll just keep asking whether or =

-   not Shark's in remote mode until you say "y" and the =

-   lisp metering code detects that that's the case.)
+By default, a shark profiling session will:
+a) use "time based" sampling, to periodically interrupt the lisp
+   process and note the value of the program counter and at least
+   a few levels of call history.
+b) do this sampling once every millisecond
+c) run for up to 30 seconds, unless told to stop earlier.
 =

-Those steps may take anywhere from "a few" to "several" seconds; steps
-2 and 3 are probably the most expensive and depend on how many
-functions are in the lisp image, how big they are, etc.
+This is known as "the default configuration"; it's possible to use
+items on the "Config" menu in the Shark application to create alternate
+configurations which provide different kinds of profiling parameters
+and to save these configurations in files for subsequent reuse.
+(The set of things that CHUD knows how to monitor is large and interesting=
.)
 =

-On every invocation of CHUD:METER, it'll tell Shark to start a
-metering session, execute the form which is its required argument,
-tell Shark to stop the session, and return the form's result(s).
+You use alternate profiling configurations (created and "exported" via
+Shark.app) with CHUD:METER, but the interface is a little awkward.
 =

-After it's been told to stop the sampling session, Shark will analyze
-the sampling data it obtained and display the results. In this
-example, it's reasonable to assume that some CCL package functions
-related to bignum multiplication dominate the execution time. Lisp
-functions that show up in Shark's session window will claim to be
-defined in the SPATCH library; their "names" will generally look like
-their printed representations.
+Reference
+---------
 =

- Limitations
+CHUD:*SHARK-CONFIG-FILE*   [Variable]
 =

-It's generally tempting to start redefining functions that have
-longer-than-expected execution times. That's possibly the right thing
-to do in general, but (because of the way that the spatch mechanism
-works) it's hard to get meaningful results: Shark can only give names
-to lisp functions that're in its .spatch file, and will continue to
-use cached informaton from that .spatch file until it quits. General
-(GC-able) lisp functions - whose code-vectors might move around in
-memory - tend to confuse Shark (and at least some versions get
-confused enough that they may crash while trying to report time spent
-in functions that aren't where they used to be ...)
+When non-null, this should be the pathname of an alternate profiling
+configuration file created by the "Config Editor" in Shark.app.
 =

-After things get a little bit out-of-whack (in terms of newly defined
-lisp functions), it's often necessary to quit both Shark and OpenMCL,
-load the new-and-improved code into the lisp, and try again, hoping
-for better results.
+(CHUD:METER form &key (reset nil) (debug-output nil))  [Macro]
 =

-After CHUD:METER has done its first-time setup, it's generally
-necessary to quit both Shark and OpenMCL if either quits in order to
-get them back in synch again.
+Executes FORM (an arbitrary lisp form) and returns whatever result(s)
+it returns, with CHUD profiling enabled during the form's execution.
+Tries to determine the name of the session file (*.mshark) to which
+the shark program wrote profiling data and opens this file in the
+Shark application.
 =

-Despite these limitations, it's probably fair to say that this is way,
-way better than nothing.
+Arguments:
 =

- Reference
+debug-output   - when non-nil, causes output generated by the shark progra=
m to
+                 be echoed to *TERMINAL-IO*.  For debugging.
+reset          - when non-nil, terminates any running instance of the
+                 shark program created by previous invocations of CHUD:MET=
ER
+                 in this lisp session, generates a new .spatch file =

+                 (describing the names and addresses of lisp functions),
+                 and starts a new instance of the shark program; if
+                 CHUD:*SHARK-CONFIG-FILE* is non-NIL when this new instance
+                 is started, that instance is told to use the specified
+                 config file for profiling (in lieu of the default profili=
ng
+                 configuration.)
 =

-(CHUD:METER form &key (duration 0) (frequency 1))  [Macro]
-
-Ensures that access to the "remote sampling facility" (Shark, usually)
-has been acquired, ensure that code vectors have been purified and
-that an spatch file for the current process is writen to the directory
-named by CHUD:*SPATCH-DIRECTORY-PATH* (or the user's home directory),
-and starts and stops the sampling facility around execution of <form>.
-Returns whatever values execution of <form> returns.
-
-Arguments
-  <form>        an arbitrary lisp expression
-  <frequency>   sampling frequency in milliseconds
-  <duration>    total number of sampling intervals, 0 implies "infinite".
-
-It seems that the <frequency> and <duration> arguments have no effect;
-the sampling frequency and duration can be set via Shark's "configuration
-editor" dialog.
-
-CHUD:*SPATCH-DIRECTORY-PATH*  [Special Variable]
-
-If non-NIL, should be a pathname whose directory component matches the
-"Patch FIles" search path in Shark's Preferences.  When this variable
-is NIL, USER-HOMEDIR-PATHNAME is used instead.
-
-
- Acknowledgments
+Acknowledgments
+---------------
 =

 Both Dan Knapp and Hamilton Link have posted similar CHUD interfaces
 to openmcl-devel in the past; Hamilton's also reported bugs in the



More information about the Openmcl-cvs-notifications mailing list