Macintosh Development |
[Home]
[About Us]
[People]
[Information Systems]
[Kerberos for Macintosh]
[Applications]
[Miscellaneous Documentation]
Version 1.3.1 of Metrowerks Profiler ships with Code Warrior 8. The information in this document pertains only to that version of Profiler. I have never seen the previous versions and I have no idea how much of this applies to them.
The idea in using the profiler is to slightly modify your code (i.e., to put the profiler calls in your code) and build your code with profiler code. Then you use the information compiler provides to improve your code's efficiency. After looping through this process several times, you remove profiler calls amd build the final version of your project.
There are six steps in profiling Metrowerks CodeWarrior projects:
They are described in detail below:
There are six profiler libraries. You should choose one depending on your project, according to the following table:
The profiler libraries require another library to be linked in your project. For 68k projects, you have to link MacOS.lib, and for PPC projects you need InterfaceLib.
To turn profiling on/off for an entire project, use the project preferences. In the processor options, select "Generate Profiler Calls" checkbox. This will also #define __profile__ 1
, so you can use #ifdef __profile__
to bracket profiler-specific code.
The first way to turn profiling on/off for a specific routine is to use ProfilerSetStatus()
. If profiling is on for the entire project, ProfilerSetStatus()
will turn profiling off is false
is passed as the parameter, or on if true
is passed.
The alternate way to accomplish this is to use #pragma
directives in C/C++. #pragma profile on
will turn profiling on for the routines declared after the directive, #pragma profile off
will turn it off, and #pragma profile reset
will revert it to preference panel settings.
The disadvantage of the second method over the first one is that the first method operates on calling chains, and the second one operates on pieces of your source, so the profiler will generate data that might not be relevat to you. For example, if routines a and b call routine c, and you turn on profiling in a and c using #pragma
s, you will also time the calls from b to c. If you use the first method that won't happen.
All you need is the following directive at the beginning of every source file that calls profiler routines:
#include <profiler.h>
At the beginning of your code, call ProfilerInit()
with this prototype:
pascal OSErr ProfilerInit (
ProfilerCollectionMethod method,
ProfilerTimeBase timeBase,
short numFunctions,
short stackDepth);
The collection method is either collectDetailed
or collectSummary
. Detailed collection requires more memory, but records data about the calling chain.
Timebase is bestTimeBase
, PPCTimeBase
, microsecondsTimeBase
, or timeMgrTimeBase
, in the decreasing accuracy order. The first one automatically select the most accurate available option; the second one is only available with PPC chips.
The remaining two parameters determine how much memory profiler will use. The data that overflows ill be lost, but you will be told so in the results. Then you can go back and alter the ProfilerInit()
parameters to preserve the data.
ProfilerInit()
return noErr
if it succeeds.
To save the data to a file, you need to call ProfilerDump()
. The data will be saved in the default directory (usually the project directory) in the MW Profiler format. (It can be exported to ASCII from the MW Profiler.) You call ProfilerDump()
with the filename of the output file. If the file already exists, a new one will be created with an asceding number appended to the name. The name has to ba a PASCAL string. For example, you can use ProfilerDump("\pTechMail");
. ProfilerDump(TechMail);
will return a File Manager error.
The results dumped are accumulated. If you want to clear the results, call ProfilerClear()
.
Before you exit the application, you must call ProfilerTerm()
. If you don't, you will leave timers running on your systems that are likely to crash it.
You cannot call UnloadSeg()
in your 68k project if you are using profiler.
Since profiler code is generated by the compiler and inserted at the entry- and exit-point of every profiled routine, you will have to step through some additional assembly code when you are tracing your porgrams. In addition to thatm you won't be able to step out of your profiled routines.
Naturally, profiler will time all the time you spend debugging profiled calls, which will skew your results.
You must remember not to kill your profiled application, because you have to call ProfilerTerm
When you open a profiler document in the profiler, the window will give you the following data:
Interpreting the data should be pretty much straightforward. To see some hints on improving your code's efficiency, you can visit the following pages:
To p[rofile PPC shared libraried, you will have to link ProfilerLIB into your project, instead of ProfilerPPC.lib. ALl the shared libraries you want to profile have to be built with Generate Profiler Calls option on.
For 68k code resources, you have to link the A4 profiler libraries. For PPC projects, you can link either of the two profiler libraries. In any case, you must make sure that the code resource is locked in memory while it is being profiled.
Documentation for this is available in electronic form in the CodeWarrior Documentation folder. Please read it :)
Metrowerks CodeWarrior and Metrowerks Profiler are copyright of Metrowerks Corporation. The Metrowerks Profiler documentation was used in creating this page.
Special thanks to Metrowerks customer support for their help.
Questions or comments? Send mail to macdev@mit.edu
Last updated on $Date: 2003/11/18 21:58:08 $
Last modified by $Author: smcguire $