home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
c
/
profil.arc
/
PROFILE.MAN
< prev
next >
Wrap
Text File
|
1989-09-04
|
11KB
|
230 lines
PROFILE(1) MS-DOS Programmer's Manual PROFILE(1)
NAME
profile - execution time statistics collector
SYNOPSIS
profile [-adin0] [-#<n>] [-m<mapfile>] [-o<outfile>] <cmdline>
DESCRIPTION
Profile(1) executes a DOS command and gathers information about where in
the program the execution time is spent. After the command has terminated,
profile(1) writes a report file where the data is presented.
Current implementations of profile(1) requires that the program under test
is linked with the MicroSoft LINK or the Borland TLINK linkers, and that a
standard format map file (as produced by the above linkers) was generated.
The link command for TLINK must contain the options '/l/c', and for the MS
LINK linker, the '/MAP' option must be specified.
Normally, profile(1) assumes a linker map file with the same name as the
executable file (including any pathes) but with the extension '.MAP' in-
stead of '.EXE'. By default the output file has the same name as the '.EXE'
file, but with extension '.PRF'. Both these conventions can be overridden.
The profiler will present it's output data summary based on the information
about public function names and addresses described by the linker map file.
If the map file is out of date, profiling results may be incorrect. Fur-
thermore, the profiler only displays public functions. One way to ensure
that interesting symbols in 'C' programs are public is to temporarily in-
sert the line
#define static
at the head of all interesting 'C' modules (this may in some cases cause
multiple definition errors in the link stage, if different functions and
variables have the same names in different modules).
In cases where lengthy execution of a command is needed to produce relia-
ble statistics, an option is available to make the profiled command run
multiple times.
Profile(1) will not process '.COM' files.
INTERNAL FUNCTIONING
Profile(1) works by first reading the linker map file and collect all the
function name and address information in memory. It then find out where in
the physical memory the executable will be loaded, and adjusts table infor-
mation according to this. Next, it installs it's own handler function for
for the PC real-time clock interrupt, and loads and executes the program.
Each time a real-time clock interrupt occurs, the interrupt handler will
record in which function the CPU was executing. This continues until the
profiled program terminates. Profile(1) then uninstalls the interrupt
handler and formats and outputs the results.
All functions described in the map file are classified either as 'intrinsic
functions' or 'user functions', according to their names: intrinsic func-
tions are those whose names start with '__', or which contain the charac-
ters '@' or '$'. All other functions are considered user functions. Apart
from the functions described in the map file, other interesting memory
areas are also defined:
'Low Mem' from 0 to 0x3ff
'DOS' from 0x400 to the beginning od the profile itself
'Profiler' from the beginning to the end of the profiler
'EGA BIOS' from 0xc0000 to 0xc7fff
'Fixed Disk BIOS' from 0xc8000 to 0xeffff
'System ROM' from 0xf0000 to 0xfe000
'System BIOS' from 0xfe000 to 0xfffff
OUTPUT LISTING FORMAT
By default, DOS areas and intrinsic functions will not be listed in the
output report (this can be overridden). Below is an excerpt of a typical
report:
Function name Addr Total Disp User
_fclose 41b1c 0.32 50.00 50.00
_daylight 4a41e 0.00 3.00 3.00
_edata 4a826 0.00 3.00 3.00
_end 4ab60 0.00 3.00 3.00
_exit 416fa 0.00 2.00 2.00
_flushall 41c02 0.00 2.00 2.00
_fopen 41c46 0.00 1.00 1.00
_fprintf 41c7e 0.00 0.50 0.50
_main 402e0 0.00 0.50 0.50
... ... ... ... ...
_timezone 4a41a 0.00 0.40 0.40
_tzname 4a420 0.00 0/30 0.30
FIARQQ 50112 0.00 0.10 0.10
FICRQQ 41112 0.00 0.01 0.01
Statistics based on 309 hits
As can be seen, functions are sorted according to their frequency of occu-
rence, and secondary by their name. They can also be sorted primarily ac-
cording to name or execution address. The first column gives name of the
function, and the second it's address at this particular instance of execu-
tion. Next is the percentage of each function related to total time, i.e.
if one adds up all DOS, intrinsic and user function percentages in this
column, the result will be 100. If DOS and intrinsics are not listed, the
total will be less than 100%.
In the second column, the percentages relative to all DISPLAYED functions
are shown. In the third, the percentages relative to all USER functions
are listed. The two latter columns should always add up very closely to
100% (the sum may not be exact due to rounding errors).
Functions that did not get any hits are not displayed by default. However,
you can force them to appear in the output listing by giving the '-0'
option in the command line.
In the last line is shown the total number of real-time clock interrupts
that occured during profiling. This value should be as large as possible,
otherwise it means the statistics is based on too little input data. See
the '#' option below to make multiple runs of the same command to increase
the statistical reliability of the data.
In the example above, it can be seen that of the displayed functions, half
the time (50%) was spent in the _fclose function. Since _fclose is also
classified as a user function, the value is the same in the third column.
But only 0.32% of the total time was spent in _fclose, indicating that most
of the program's execution time is spent doing system calls into DOS or
other system resources. To find out, one could include DOS and intrinsic
functions in the output listing by using the '-d' and/or '-i' options.
OPTIONS
-a Sort the output list in order of execution address, and not
by frequency.
-d Include DOS and BIOS areas, and the profiler itslef, in the
output list.
-i Include intrinsic functions in the output list.
-n Sort the output list in order of function name, and not by
frequency.
-0 Normally functions that did not get any hits during execution
are not listed in the output. The '-0' option causes them to
be listed.
-#<n> Execute the profiled command <n> times to increase the relia-
bility of the statistics (default 1).
-m<mapfile> Read the linker map from file <mapfile>. The default is the
same name as the executable, but with extension '.MAP'.
-o<outfile> Write output data to file <outfile>. The default is the same
name as the executable, but with extension '.OUT'.It is poss-
ible to write the data directly to 'CON' or to the printer
device.
<cmdline> The normal command line for the profiled command. Note that
profile(1) will not follow the DOS 'PATH' environment variable
to find the executable file. If you want to profile a command
that is in another directory, the explicit path to it must be
supplied. But the '.exe' extension should NOT be specified.
Example:
C> profile ..\tst\tester junk <cr>
will profile the 'tester.exe' program in directory /..\tst'.
Note that in this example, the map file is assumed to be in
the '..\tst' directory too, and the profiler output file will
also be written to that directory.
SPECIAL OPTIONS, NOT NORMALLY USED
-? Report the memory address of profile(1)'s own PSP and main()
function. Used only during development of profile(1).
-$ Report the memory address of the first free memory (approxi-
mately where the profiled command will be loaded). Used only
during development of profile(1). '-$' also causes more infor-
mation to be included in the output listing.
DIAGNOSTICS
Illegal command line option: `x'
No command specified for profiling
Cannot find executable `x'
`x' is a directory
Cannot find linker map file `x'
Output file `x' is write-protected
Invalid map file format in `x'
Insufficient memory for function tables
Not enough function table slots
Cannot open output file `x'
Insufficient memory to execute command
Error executing command `x'
Invalid EXE file format in `x'
Program ran too fast - no hits!
BUGS
The method for finding out the address where the profiled command will be
loaded is compiler specific (to the compiler used to compile profile(1)).
It involves giving the command
C> profile -$ profile -? <cr>
These two (!) instances of profile will produce some special output. The
one which EXECUTES the other will show what memory address it thinks is the
lowest free one. The one which IS EXECUTED by the other will report the
address of it's own Program Segment Prefix and main() function. Naively,
the two values would be expected to be the same, but they are not.
The discrepancy should be added during the adjustment of function addresses
to actual execution values. This is a nuisance. The values may even be dif-
ferent if you change the source code using the same compiler, so if you mo-
dify profile(1) you should check the address of the real executing main()
function and the assumed address for it and check that the values agree
after each change to the sources.
It could be considered to have some kind of regular expression format, per-
haps read from a specification file, that tells what functions should be
included in or excluded from the output report.
Other bugs? No doubt!
NOTES
The writing of this command was inspired by a profiler distributed on Use-
Net by Diomidis Spinellis. Although his profile is very well written and
performs as described, it has two shortcomings. One is that the profiled
program has to be modified with a call to a special function that is linked
into it. Second, and much more serious: if you break out of the profiled
program with CTRL-C, the interrupt handler will not be restored, and as
soon as the memory used for it is overwritten by another command, the PC
dies immediately.
This profile(1) does noit suffer from these problems (but possibly from
many others...). Although I have taken some ideas from Diomidis' version,
most of this one is original work. It is hereby placed in the public do-
main.
Author: Bjorn Larsson uucp: bl@infovox.se
Ynglingagatan 5, IV
S-113 47 Stockholm
SWEDEN