Fortran Programming Guide | ![]() ![]() ![]() ![]() ![]() |
Performance Profiling
This chapter describes how to measure and display program performance. Knowing where a program is spending most of its compute cycles and how efficiently it uses system resources is a prerequisite for performance tuning.
Sun WorkShop Performance Analyzer
Sun WorkShop Performance Analyzer provides a sophisticated pair of tools for collecting and analyzing program performance data:
- The Sampling Collector collects performance data (statistical profiles of call stacks, thread-synchronization delay events, hardware-counter overflow profiles, address space data, and summary information for the operating system), and stores it in an experiment file.
- The Sampling Analyzer displays the data recorded by the Sampling Collector, so you can examine the information. The analyzer processes the data and displays various metrics of performance, at function, caller-callee, source-line, disassembly-instruction, and program levels.
- The Sampling Analyzer can also help you to fine-tune your application's performance, by creating a mapfile you can use to improve the order of function loading in the application address space.
The Collector and Analyzer are designed for use by any software developer, even if performance tuning is not the developer's main responsibility.
Command-line equivalents of the Collector and Analyzer are available:
dbx
includes a data-collection feature that has the same functionality as the Collector.- The command-line utility
er_print
(1), which prints out an ASCII version of the various Analyzer displays, operates as a command-line sampling analyzer.Details can be found in the Sun WorkShop manual Analyzing Program Performance With Sun WorkShop.
The
time
CommandThe simplest way to gather basic data about program performance and resource utilization is to use the
time
(1) command or, incsh
, theset
time
command.Running the program with the
time
command prints a line of timing information on program termination.
demo%time myprog
The Answer is: 543.016.5u 17.1s 1:16 31% 11+21k 354+210io 135pf+0wdemo%user system wallclock resources memory I/O paging
- user - 6.5 seconds in user code, approximately
- system - 17.1 seconds in system code for this task, approximately
- wallclock - 1 minute 16 seconds to complete
- resources - 31% of system resources dedicated to this program
- memory - 11 Kilobytes of shared program memory, 21 kilobytes of private data memory
- I/O - 354 reads, 210 writes
- paging - 135 page faults, 0 swapouts
Multiprocessor Interpretation of
time
OutputTiming results are interpreted in a different way when the program is run in parallel in a multiprocessor environment. Since
/bin/time
accumulates the user time on different threads, only wall clock time is used.Since the user time displayed includes the time spent on all the processors, it can be quite large and is not a good measure of performance. A better measure is the real time, which is the wall clock time. This also means that to get an accurate timing of a parallelized program you must run it on a quiet system dedicated to just your program.
The
gprof
Profiling CommandThe
gprof
(1) command provides a detailed postmortem analysis of program timing at the subprogram level, including how many times a subprogram was called, who called it, whom it called, and how much time was spent in the routine and by the routines it called.To enable
gprof
profiling, compile and link the program with the-pg
option:
demo%f77 -o Myprog -fast -pg Myprog.f ...
demo%Myprog
demo%gprof Myprog
The program must complete normally for
gprof
to obtain meaningful timing information.At program termination, the file
gmon.out
is automatically written in the working directory. This file contains the profiling data that will be interpreted bygprof
.Invoking
gprof
produces a report on standard output. An example is shown on the next pages. Not only the routines in your program are listed but also the library procedures and the routines they call.The report is mostly two profiles of how the total time is distributed across the program procedures: the call graph and the flat profile. They are preceded by an explanation of the column labels, followed by an index. (The
gprof -b
option eliminates the explanatory text; see thegprof
(1) man page for other options that can be used to limit the amount of output generated.)In the graph profile, each procedure (subprogram, procedure) is presented in a call-tree representation. The line representing a procedure in its call-tree is called the function line, and is identified by an index number in the leftmost column, within square brackets; the lines above it are the parent lines; the lines below it, the descendant lines.
The call graph profile is followed by a flat profile that provides a routine-by-routine overview. An (edited) example of
gprof
output follows.
Note User-defined functions appear with their Fortran names followed by an underscore. Library routines appear with leading underscores.
The call graph profile:
The flat profile overview:
- Function Line.
The function line [5] in the preceding example reveals that:
cheb1
was called 6000 times-- 3000 fromderiv
, 3000 fromdiffr
.- 2.58 seconds were spent in
cheb1
itself.- 5.81 seconds were spent in routines called by
cheb1
.- 65.7% of the execution time of the program was within
cheb1
.- Parent Lines.
- The parent lines above [5] indicate that
cheb1
was called from two routines,deriv
anddiffr
. The timings on these lines show how much time was spent incheb1
when it was called from each of these routines.
- Descendant Lines.
- The lines below the function line indicate the routines called from
cheb1
,fftb,sin,
andcos
. The library sine function is called indirectly.
- Flat Profile.
- Function names appear on the right. The profile is sorted by percentage of total execution time.
Overhead and Other Considerations
Profiling (compiling with the
-pg
option) may greatly increase the running time of a program. This is due to the extra overhead required to clock program performance and subprogram calls. Profiling tools likegprof
attempt to subtract an approximate overhead factor when computing relative runtime percentages. All other timings shown may not be accurate due to UNIX and hardware timekeeping inaccuracies.Programs with short execution times are the most difficult to profile because the overhead may be a significant fraction of the total execution time. The best practice is to choose input data for the profiling run that will result in a realistic test of the program's performance. If this is not possible, consider enclosing the main computational part of the program within a loop that effectively runs the program N times. Estimate actual performance by dividing the profile results by N.
The Fortran library includes two routines that return the total time used by the calling process. See the man pages for
dtime
(3F) andetime
(3F).Also,
gprof
can give misleading results. A well-known limitation is thatgprof
cannot differentiate time spent in a function called from more than one caller. For example, it may be that functionFU
takes much more time when called from routineBAR
than from any other routine, and knowing this could suggest to you a significant restructuring of the program and better performance. Unfortunatly, the results shown by gprof average the total time spent in FU over all calls, obscuring this valuable bit of information. The Sun WorkShop Performance Analyzer provides much more detailed and useful information if you intend to do serious performance analysis of a program, and should be used instead.The
tcov
Profiling CommandThe
tcov
(1) command, when used with programs compiled with the-a,
or
-xa,-xprofile=tcov
options, produces a statement-by-statement profile of the source code showing which statements executed and how often. It also gives a summary of information about the basic block structure of the program.There are two implementations of
tcov
coverage analysis. The originaltcov
is invoked by the-a
or-xa
compiler options. Enhanced statement level coverage is invoked by the-xprofile=tcov
compiler option and the-x tcov
option. In either case, the output is a copy of the source files annotated with statement execution counts in the margin. Although these two versions oftcov
are essentially the same as far as the Fortran user is concerned (most of the enhancements apply to C++ programs), there will be some performance improvement with the newer style.
Note The code coverage report produced bytcov
will be unreliable if the compiler has inlined calls to routines. The compiler inlines calls whenever appropriate at optimization levels above-O3
, and according to the-inline
option. With inlining, the compiler replaces a call to a routine with the actual code for the called routine. And, since there is no call, references to those inlined routines will not be reported bytcov
. Therefore, to get an accurate coverage report, do not enable compiler inlining.
"Old Style"
tcov
Coverage AnalysisCompile the program with the
-a
(or-xa
) option. This produces the file$TCOVDIR/
file.d
for each source.f
file in the compilation. (If environment variable$TCOVDIR
is not set at compile time, the.d
files are stored in the current directory.)Run the program (execution must complete normally). This produces updated information in the
.d
files. To view the coverage analysis merged with the individual source files, runtcov
on the source files. The annotated source files are named$TCOVDIR/
file.tcov
for each source file.The output produced by tcov shows the number of times each statement was actually executed. Statements that were not executed are marked with
####->
to the left of the statement.Here is a simple example:
"New Style" Enhanced
tcov
AnalysisTo use new style
tcov
, compile with-xprofile=tcov
. When the program is run, coverage data is stored in program.profile/tcovd
, where program is the name of the executable file. (If the executable werea.out
,a.out.profile/tcovd
would be created.)Run
tcov -x
dirname source_files to create the coverage analysis merged with each source file. The report is written to file.tcov
in the current directory.Running a simple example:
Environment variables
$SUN_PROFDATA
and$SUN_PROFDATA_DIR
can be used to specify where the intermediary data collection files are kept. These are the*.d
andtcovd
files created by old and new styletcov
, respectively.Each subsequent run accumulates more coverage data into the
tcovd
file. Data for each object file is zeroed out the first time the program is executed after the corresponding source file has been recompiled. Data for the entire program is zeroed out by removing thetcovd
file.These environment variables can be used to separate the collected data from different runs. With these variables set, the running program writes execution data to the files in
$SUN_PROFDATA_DIR/$SUN_PROFDATA/
.Similarly, the directory that
tcov
reads is specified bytcov -x $SUN_PROFDATA
. If$SUN_PROFDATA_DIR
is set,tcov
will prepend it, looking for files in$SUN_PROFDATA_DIR/$SUN_PROFDATA/
, and not in the working directory.For the details, see the
tcov
(1) man page.
f77
I/O ProfilingYou can obtain a report about how much data was transferred by your program. For each Fortran unit, the report shows the file name, the number of I/O statements, the number of bytes, and some statistics on these items.
To obtain an I/O profiling report, insert calls to the library routines start_iostats and end_iostats around the parts of the program you wish to measure. (A call to end_iostats is required if the program terminates with an
END
orSTOP
statement rather than aCALL
EXIT
.)
Note The I/O statements profiled are:READ
,WRITE
,OPEN
,CLOSE
,INQUIRE
,BACKSPACE
,ENDFILE
, andREWIND
. The runtime system opensstdin
,stdout
, andstderr
before the first executable statement of your program, so you must explicitly reopen these units after the call tostart_iostats
.
Example: Profile
stdin
,stdout
, andstderr
:
EXTERNAL start_iostats...CALL start_iostatsOPEN(5)OPEN(6)OPEN(0)If you want to measure only part of the program, call
end_iostats
to stop the process. A call toend_iostats
may also be required if your program terminates with anEND
orSTOP
statement rather thanCALL
EXIT
.The program must be compiled with the
-pg
option. When the program terminates, the I/O profile report is produced on the file name.io_stats
, where name is the name of the executable file.Here is an example:
Each pair of lines in the report displays information about an I/O unit. One section shows input operations and another shows output. The first line of a pair displays statistics on the number of data elements transferred before the unit was closed. The second row of statistics is based on the number of I/O statements processed.
In the example, there were 6 calls to write a total of 26 data elements to standard output. A total of 248 bytes was transferred. The display also shows the average and standard deviation in bytes transferred per I/O statement (9.538 and 1.63, respectively), and the average and standard deviation per I/O statement call (42.33 and 3.266, respectively).
The input report also contains a column to indicate whether a unit was memory mapped or not. If mapped, the number of mmap() calls is recorded in parentheses in the second row of the pair.
The output report indicates block sizes, formatting, and access type. A file opened for direct access shows its defined record length in parentheses in the second row of the pair.
Note Compiling with environment variableLD_LIBRARY_PATH
set might disable I/O profiling, which relies on its profiling I/O library being in a standard location.
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |