Using Apple's CHUD metering tools from CCL
==========================================
Prerequisites
-------------
Apple's CHUD metering tools are available (as of this writing) from:
.
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.
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:
shell> shark --help
and verifying that that prints a usage summary.
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.
Two of the CHUD component programs are of particular interest:
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.
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.
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".
Usage synopsis
--------------
? (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
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.
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:
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:
profiling-session--_--_..
where is the lisp's process id, is the name of
the lisp kernel (of all things ...), and the other values provide
a timestamp.
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
3) run the shark program ("/usr/bin/shark") and wait until it's ready to
receive signals that control its operation.
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.)
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
Profiling "configurations".
--------------------------
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.
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.)
You use alternate profiling configurations (created and "exported" via
Shark.app) with CHUD:METER, but the interface is a little awkward.
Reference
---------
CHUD:*SHARK-CONFIG-FILE* [Variable]
When non-null, this should be the pathname of an alternate profiling
configuration file created by the "Config Editor" in Shark.app.
(CHUD:METER form &key (reset nil) (debug-output nil)) [Macro]
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.
Arguments:
debug-output - when non-nil, causes output generated by the shark program 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:METER
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 profiling
configuration.)
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
spatch mechanism to CHUD developers (and gotten those bugs fixed.)