| 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:
dbxincludes 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
timeCommandThe simplest way to gather basic data about program performance and resource utilization is to use the
time(1) command or, incsh, thesettimecommand.Running the program with the
timecommand prints a line of timing information on program termination.
demo%time myprogThe 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
timeOutputTiming results are interpreted in a different way when the program is run in parallel in a multiprocessor environment. Since
/bin/timeaccumulates 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
gprofProfiling 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
gprofprofiling, compile and link the program with the-pgoption:
demo%f77 -o Myprog -fast -pg Myprog.f ...demo%Myprogdemo%gprof MyprogThe program must complete normally for
gprofto obtain meaningful timing information.At program termination, the file
gmon.outis automatically written in the working directory. This file contains the profiling data that will be interpreted bygprof.Invoking
gprofproduces 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 -boption 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
gprofoutput 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:
cheb1was called 6000 times-- 3000 fromderiv, 3000 fromdiffr.- 2.58 seconds were spent in
cheb1itself.- 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
cheb1was called from two routines,derivanddiffr. The timings on these lines show how much time was spent incheb1when 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
-pgoption) 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 likegprofattempt 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,
gprofcan give misleading results. A well-known limitation is thatgprofcannot differentiate time spent in a function called from more than one caller. For example, it may be that functionFUtakes much more time when called from routineBARthan 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
tcovProfiling CommandThe
tcov(1) command, when used with programs compiled with the-a,or
-xa,-xprofile=tcovoptions, 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
tcovcoverage analysis. The originaltcovis invoked by the-aor-xacompiler options. Enhanced statement level coverage is invoked by the-xprofile=tcovcompiler option and the-x tcovoption. In either case, the output is a copy of the source files annotated with statement execution counts in the margin. Although these two versions oftcovare 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 bytcovwill 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-inlineoption. 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"
tcovCoverage AnalysisCompile the program with the
-a(or-xa) option. This produces the file$TCOVDIR/file.dfor each source.ffile in the compilation. (If environment variable$TCOVDIRis not set at compile time, the.dfiles are stored in the current directory.)Run the program (execution must complete normally). This produces updated information in the
.dfiles. To view the coverage analysis merged with the individual source files, runtcovon the source files. The annotated source files are named$TCOVDIR/file.tcovfor 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
tcovAnalysisTo 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/tcovdwould be created.)Run
tcov -xdirname source_files to create the coverage analysis merged with each source file. The report is written to file.tcovin the current directory.Running a simple example:
Environment variables
$SUN_PROFDATAand$SUN_PROFDATA_DIRcan be used to specify where the intermediary data collection files are kept. These are the*.dandtcovdfiles created by old and new styletcov, respectively.Each subsequent run accumulates more coverage data into the
tcovdfile. 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 thetcovdfile.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
tcovreads is specified bytcov -x $SUN_PROFDATA. If$SUN_PROFDATA_DIRis set,tcovwill 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.
f77I/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
ENDorSTOPstatement rather than aCALLEXIT.)
Note The I/O statements profiled are:READ,WRITE,OPEN,CLOSE,INQUIRE,BACKSPACE,ENDFILE, andREWIND. The runtime system opensstdin,stdout, andstderrbefore 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_iostatsto stop the process. A call toend_iostatsmay also be required if your program terminates with anENDorSTOPstatement rather thanCALLEXIT.The program must be compiled with the
-pgoption. 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_PATHset 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 |