[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

 

Chapter 8.

 

Profiler Reference



This chapter contains the detailed technical reference information you may need when using the profiler.

The topics discussed include:


Compiler Directives

You can control routine-level profiling using compiler directives.

The C/C++ compiler supports three preprocessor directives that you can use to turn compiling on and off at will.

 

#pragma profile on  
enables calls to the profiler in functions that are declared following the pragma  
#pragma profile off  
disables calls to the profiler in functions that are declared following the pragma  
#pragma profile reset  
sets the profile setting to the value selected in the preferences panel  

You can use these directives to turn profiling on for any functions you want to profile, regardless of the settings in the Processor preferences. You can also turn off profiling for any function you don't want to profile.


Testing for the Profiler

As there are compiler directives to turn the profiler on and off, there are also directives to test if the profiler is on. You can use these tests in your code so that you can run your program with or without the profiler and not have to modify your code each time.

In C/C++, use the #if-#endif clause. For example:


void main()
{
#if __profile__    // is the profiler on?
	if (!ProfilerInit(collectDetailed, bestTimeBase, 20, 5))
	{
#endif
		test(15);
#if __profile__
		ProfilerDump("\pExample.prof");
		ProfilerTerm();
	}
#endif
}

In Pascal, use the following test:


{$IFC OPTION(PROF)}
	if (ProfilerInit(collectDetailed, bestTimebase,
						100, 20) = noErr) then begin
{$ENDC}

See also "Routine-level profiling."


Memory Usage

The profiler allocates two buffers in temporary memory to hold data as it collects information about your code: one based on the number of routines, and one based on the stack depth. You pass these parameters in your call to ProfilerInit().

In summary collection mode, the profiler allocates 64 bytes * numFunctions and 40 bytes * stackDepth.

In detailed collection mode, the profiler allocates 12 * 64 * numFunctions bytes and 40 * stackDepth bytes.

As an example, assume numFunctions is set to 100, and stackDepth to 10. In summary mode the profiler allocates buffers of 6,400 bytes and 400 bytes. In detailed mode it allocates buffers of 76,800 bytes and 400 bytes.

ProfilerGetDataSizes() lets you query the profiler for the current size of the data collected in the function and stack tables. This information can be used to tune the parameters passed to ProfilerInit().

See also "ProfilerInit()."


Time and Timebases

The CodeWarrior profiler supports four timebases. A timebase is the clock interval used to measure time in a routine. The shorter the interval, the more precise the measurements.

When you call ProfilerInit() you specify the desired timebase. The constant bestTimeBase tells the profiler to figure out the most precise timebase available on your platform and to use it.

Table 8.1 describes each timebase:

Profiler timebases:

 

Timebase
Description
bestTimeBase  
This is the preferred timebase. Using this timebase, the profiler selects the timebase with the highest resolution for your machine.  
PPCTimeBase  
This timebase is only available on a Power Macintosh from PowerPC code. It cannot be used in 68k code. It uses the built-in timing facilities of the PowerPC processor. On a 601 it uses the RTC registers. On subsequent PowerPC processors it uses the TB registers. This timebase is very low overhead and high accuracy. If this timebase is specified but not available, ProfilerInit() returns paramErr.  
microsecondsTimeBase  
This timebase uses the _Microseconds trap to measure time. It has the same accuracy as the timeMgrTimeBase, but less overhead (one trap vs. three traps). This timebase may not be available on all Macintosh computers. If this timebase is specified but not available, ProfilerInit() returns paramErr.  
timeMgrTimeBase  
This timebase uses the microseconds timing ability of the Time Manager. This is more accurate than the ticksTimeBase, (~20 µs), but has more overhead. On a Power Macintosh running System 7.1.2, the traps called run emulated, so there are three mixed mode switches for every routine call. This timebase is available on all Macintoshes with System 7.0 or greater.  
ticksTimeBase  
This counter increments 60 times a second. It is a very low overhead timebase with coarse accuracy. This timebase is available on all Mac OS computers.  


WARNING!

PPCTimeBase does not work correctly under Mac OS X. If you use it, you actually get microseconds timing instead.



Profiler Menu Reference

This reference section discusses the functionality of each menu item in MW Profiler, the data viewing application for the CodeWarrior profiler system.

These are the main menus:


About MW Profiler

Choosing About Metrowerks Profiler from the Apple menu displays copyright and author information about the application.


File Menu

The File menu contains commands to open, close, save, and print documents, and to quit the application, as illustrated in Figure 8.1.

The File menu:

Open displays the standard open file dialog that allows you to select and open an existing MW Profiler document.

Close closes the active window.

Save Report As or Save As saves the contents of the active window as a tab-delimited text document. The text file is organized the same way that the window is organized.

Generate Arrange File generates a link arrangement file using a depth-first traveral algorithm. The final .arr file can then be linked back into your project to produce even faster code.

Generate Weighted Arrange File is the same as Generate Arrange File but uses a true call frequency ordering algorithm which produces better results. The final .arr file can then be linked back into your project to produce even faster code.

Page Setup or Print Setup displays the standard page setup dialog for the current printer.


TIP

To fit the profiler output across one page, select landscape orientation and 85% reduction.


Print Preview shows what the data file will look like when you print it out on paper.

Print prints the MW Profiler document in accord with the current view and sort order in the window.

Quit quits the MW Profiler application.


Edit Menu

All Edit menu items are disabled. There is nothing to cut, copy, paste, clear, or select in an MW Profiler window.


View Menu

The View menu contains commands to sort and view MW Profiler data. The currently active option has a check mark in front of the menu item. You may also click on the column header to sort the data by the values in that column. Figure 8.2 shows the options that you can choose.

The View menu:


Windows Menu

The windows menu lists all the open profiler data windows.


Profiler Function Reference

This is a reference for all Profiler functions mentioned in the text of this manual. The functions described in this chapter are:


Profiler API

The discussion of each function includes the following attributes:


ProfilerInit()

Description :

ProfilerInit() prepares the profiler for use and turns the profiler on. The parameters tell the profiler how this collection run is going to operate, and how much memory to allocate. ProfilerInit() must be the first profiler call before you can call any other routine in the profiler API.

Prototypes:
  typedef enum {    collectDetailed,
   collectSummary
  } ProfilerCollectionMethod;

  typedef enum {    ticksTimeBase,
   timeMgrTimeBase,
   microsecondsTimeBase,
   PPCTimeBase,
   bestTimeBase
  } ProfilerTimeBase;

  pascal OSErr ProfilerInit(    ProfilerCollectionMethod method,
   ProfilerTimeBase timeBase,
   long numFunctions,short stackDepth);
Remarks :

ProfilerInit() attempts to allocate memory in the Process Manager heap (temporary memory). If it can't get the required memory in that heap, it tries in the current heap. This strategy minimizes the effect that the profiler has on the application's memory partition.

ProfilerInit() can return memory manager errors such as memFullErr and paramErr. If paramErr is returned, it means that one of the constants passed in was out of range, or that Profiler-Init() has already been called.

The method and timeBase parameters select the appropriate profiler options. The numFunctions parameter indicates the number of routines in the program for which the profiler should allocate buffer storage. If the profiler is operating in detailed mode, this number is internally increased (exponentially), because of the branching factors involved. The stackDepth parameter indicates how many routines deep the stack can get.

A call to ProfilerInit() must be followed by a matching call to ProfilerTerm().


ProfilerTerm()

Description:

ProfilerTerm() stops the profiler and deallocates the profiler's buffers. It calls ProfilerDump() to dump out any information that has not been dumped. ProfilerTerm() must be called at the end of a profile session.

Prototypes:   void ProfilerTerm( void );
Remarks :

If a program exits after calling ProfilerInit() without calling ProfilerTerm(), timers may be left running that could crash the machine.


ProfilerSetStatus()

Description :

ProfilerSetStatus() lets you turn profiler recording on and off in the program. This makes it possible to profile specific sections of your code such as screen redraw or a calculation engine. The profiler output makes more sense if the profiler is turned on and off in the same routine, rather than in different routines.

Prototypes:   pascal void ProfilerSetStatus( short on );
Remarks :

This routine and ProfilerGetStatus() are the only profiler routines that may be called at interrupt time.

Pass 1 to turn recording on and 0 to turn recording off.


ProfilerGetStatus()

Description:

ProfilerGetStatus() lets you query the profiler to determine if it is collecting profile information.

Prototypes:   pascal short ProfilerGetStatus( void );
Remarks:

This routine and ProfilerSetStatus() are the only profiler routines that may be called at interrupt time.

ProfilerGetStatus() returns a 1 if the profiler is currently recording, 0 if it is not.


ProfilerGetDataSizes()

Description:

ProfilerGetDataSizes() lets you query the profiler for the current size of the data collected in the function and stack tables. This information can be used to tune the parameters passed to ProfilerInit().

Prototypes:
  pascal void ProfilerGetDataSizes(    long *functionSize,
   long *stackSize);
Remarks:

If you have passed collectDetailed to ProfilerInit(), ProfilerGetDataSizes() returns the number of actual routines in the table, which may be larger than the value passed to ProfilerInit() in numFunctions. This is because the profiler multiplies numFunctions by 12 when it allocates the table. The multiplication is done so that you can easily switch between collectDetailed and collectSummary methods without changing the parameters.


ProfilerDump()

Description:

ProfilerDump() dumps the current profile information without clearing it. The filename passed must be a Pascal string.

Prototypes:   pascal OSErr ProfilerDump( StringPtr filename );
Remarks:

This can be useful for dumping intermediate results on a long task. If the specified file already exists, a new file is created with an incrementing number appended to the filename. This allows the dump to be called inside a loop with a constant filename.

ProfilerDump() can return memory manager errors such as memFullErr, or file system errors.


ProfilerClear()

Description:

ProfilerClear() clears any profile information from the buffers.

Prototypes:   pascal void ProfilerClear( void );
Remarks:

ProfilerClear() retains the settings of collectionMethod and timeBase that were set by ProfilerInit(). It does not deallocate the buffers.


ProfilerCreateThread()

Description:

Use ProfilerCreateThread() to create a profiler thread structure to track the information in a new thread. You should call this routine whenever you create a new thread. This call creates the necessary profiler buffers and returns a reference used by the profiler. The threadRef provided by this routine must be stored with the thread and passed to ProfilerSwitchToThread() in the thread's swapIn proc.

Prototypes:
  typedef unsigned long ProfilerThreadRef;   pascal OSErr ProfilerCreateThread(
   short stackSize, long byteStackSize,
   ProfilerThreadRef *threadRef);
Remarks:

The stackSize parameter is the number of profiler frames to use. The byteStackSize parameter is the size in bytes of the stack that was created. This is done so that you can use these routines with any threads package, the profiler does not include any explicit calls to the Thread Manager.

This routine allocates memory in the current heap.


ProfilerDeleteThread()

Description:

When a thread terminates, call ProfilerDeleteThread() to clean up the profiler thread tracking structures.

Prototypes:
  pascal void ProfilerDeleteThread(    ProfilerThreadRef thread);
Remarks:

Returns paramErr if the ProfilerThreadRef passed in is not a threadRef returned from ProfilerCreateThread().


ProfilerSwitchToThread()

Description:

Call ProfilerSwitchToThread() from the swapIn proc of the thread, passing the threadRef returned from ProfilerCreateThread().

Prototypes:
  pascal void ProfilerSwitchToThread(    ProfilerThreadRef thread);
Remarks:

Returns paramErr if not a threadRef returned from ProfilerCreate-Thread().


ProfilerGetMainThreadRef()

Description:

ProfilerGetMainThreadRef() returns the threadRef of the implicitly created main thread. threadRef is a pointer to an internal data structure.

Prototypes:
  pascal ProfilerThreadRef ProfilerGetMainThreadRef(); Remarks:

Use this call to get the threadRef. Necessary to switch back to the main thread with ProfilerSwitchToThread().


TIP

PowerPlant has been set up to make the profiler thread calls for you. Look at the threads classes for examples on how to use the profiler thread routines.


 


[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

Visit the Metrowerks website at: http://www.metrowerks.com
For assistance contact Metrowerks Technical Support at: cw_support@metrowerks.com
Copyright © 2000, Metrowerks Corp. All rights reserved.

Last updated: July 21, 2000