Performance Profiling Tools |
|
![]() |
This document is organized into the following sections:
Introduction
Performance analysis tools provide a variety of analysis levels. Analysis levels vary from simple timing of a command to a statement-by-statement analysis of a program. Select the level of granularity based on the amount of detail and optimization you wish to perform. Here are the performance analysis tools available from the simplest to the most detailed:
For example, a C source file called index.assist.c produces a program called index.assist. To compile a program for profiling, use either the -p or -qp option to the compiler:
% cc -p -o index.assist index.assist.cNow run the index.assist program. Each time it runs, profiling data is sent to a file called mon.out at the end of the run. Every time you run the program a new mon.out file is created, overwriting the old version. You then use the prof command to interpret the results of the profile:
% index.assistFigure 1 on page 3 shows a sample prof output.
% ls mon.out
mon.out
% prof index.assist
Figure 1 Sample prof Output
It is not obvious from the flat call graph that compare_strings is heavily recursive, but you can deduce this by using the call graph profile described in the next section. In this particular case, improving the algorithm also reduces the number of calls.
Using the same index.assist program as an example, compile the program for call graph profiling. Use the
-xpg
option to the C compiler or the -pg
option to other compilers:
% cc -xpg -o index.assist index.assist.cNow run the index.assist program as before. When a program is compiled in this manner, each time it is run, call-graph profile data is sent to a file called gmon.out at the end of the run. This file is re-created each time you run the program. Use the gprof command to interpret the results of the profile. The output from gprof is voluminous--it's usually intended that you take the summaries away and read them later. For that reason, redirect the output to a file, /tmp/g.output:
% index.assistThe output from gprof consists of two major items:
% ls gmon.out
gmon.out
% gprof index.assist > /tmp/g.output
granularity: each sample hit covers 4 byte(s) for 0.14% of 14.74 secondsThis is part of the call graph profile:
Figure 2 Sample gprof Output
tcov works with both C and C++ programs, but tcov does not support files that contain #line or #file directives. tcov does not enable test coverage analysis of the code in the #include header files. Applications compiled with -xa (C), -a (other compilers), and +d (C++) run slower than normal. The +d option inhibits expansion of C++ inline functions, and updating the .d file for each execution takes considerable time.
-xa
option to the C compiler, or the -a
option of other compilers:
% cc -xa -o index.assist index.assist.cThe C compiler generates an index.assist.d file, containing database entries for the basic blocks present in index.assist.c. When the program index.assist is run till completion, the compiler updates the index.assist.d file. The count of basic blocks cannot exceed the value represented by an unsigned int.
The index.assist.d file is created in the directory specified by the environment variable TCOVDIR, which is set as follows:
In a Bourne Shell:
$ TCOVDIR=directoryIn a C Shell:
$ export TCOVDIR
% setenv TCOVDIR directoryIf TCOVDIR is not set, index.assist.d is created in the current directory.
Having compiled index.assist.c, run index.assist.
% index.assist % ls *.d index.assist.d |
% tcov index.assist.c % ls *.tcov index.assist.tcov |
Figure 3 shows a small fragment of the C code from one of the modules of index.assist--the module in question is the insert_index_entry function called so recursively.
Figure 3 Sample tcov Output
Figure 4 tcov Basic Block Coverage
Creating Profiled Shared Libraries
It is possible to create a profiled shareable library and use it in place of one where binaries have already been linked. Include the -xa (C) or
-a (other compilers) option when creating the shareable libraries.
For example:%cc -G -xa -o foo.so.1 foo.o
This command includes a copy of the tcov profiling subroutines in the shareable libraries, so that clients of the library do not need to relink. If a client of the library is also linked for profiling, then the version of the tcov subroutines used by the client is used to profile the shareable library. Locking Files
tcov uses a simple file-locking mechanism for updating the block coverage database in the .d files. It employs a single file, /tmp/tcov.lock, for this purpose. Consequently, only one executable compiled with -xa (C) or -a (other compilers) should be running on the system. If the execution of the program compiled with the -xa (or -a) option is manually terminated, then the /tmp/tcov.lock file has to be deleted manually.tcov_exit: Failed to create lock file
The stored information is not updated. This locking is safe across a network. Since locking is performed on a file-by-file basis, other files may be correctly updated.
'/tmp_mnt/net/rbbb/export/home/src/newpattern/foo.d.lock'
for coverage data file
'/tmp_mnt/net/rbbb/export/home/src/newpattern/foo.d'
after 5 tries. Is somebody else running this binary?
Reading Errors From tcov Subroutines
The following error messages occur from tcov subroutines:tcov_exit: Could not open coverage data file
The user running the binary lacks permission to read or write to the coverage data file. The problem also occurs if the coverage data file has been deleted.
'coverage data file name' because
'system error message string'.
tcov_exit: Could not write coverage data file
The user running the binary lacks permission to write to the directory containing the coverage data file. The problem also occurs if the directory containing the coverage data file is not mounted on the machine where the binary is being run.
'coverage data file name' because
'system error message string'.
tcov_exit: Failed to create lock file 'lock file name' for
coverage data file 'coverage data file name' after 5 tries. Is
someone else running this executable?
Too many users are trying to update a coverage data file at the same time. The problem also occurs if a machine has crashed while a coverage data file is being updated, leaving behind a lock file. In the event of a crash, the longer of the two files should be used as the post-crash coverage data file. Manually remove the lock file.tcov_exit: Stdio failure, probably no memory left.
No memory is available, and the standard I/O package will not work. You cannot update the coverage data file at this point.tcov_exit: Coverage data file path name too long (length
characters) 'coverage data file name'.
The lock file name contains six more characters than the coverage data file name; therefore, the derived lock file name may not be legal.tcov_exit: Coverage data file 'coverage data file name' is too
short. Is it out of date?
A library or binary with tcov profiling enabled is simultaneously being run, edited, and recompiled. The old binary expects a coverage data file of a certain size, but the editing often changes that. If the compiler creates a new coverage data file at the same time the old binary is trying to update the old coverage data file, the binary may see an apparently empty or corrupt coverage file.
tcov Enhanced--Statement-level Analysis
tcov Enhanced gives line-by-line information on how a program executes. It produces a copy of the source file, annotated to show which lines are used and how often. It also gives a summary of information about basic blocks. tcov Enhanced works with both C and C++ source files.-xa
(C), -a
(other compilers), and +d
(C++) run slower than norma. The +d
option inhibits expansion of C++ inline functions, and updating the .d file for each execution takes considerable time. Using the index.assist Program With tcov Enhanced
For a description of how to use the index.assist program for the original tcov see "Using the index.assist Program for Use With tcov" on page 8.
tcov Enhanced has the same basic user model as the original tcov:
-xprofile=tcov
option (for all compilers):% cc -xprofile=tcov -o index.assist index.assist.c
tcov Enhanced, unlike tcov, does not produce a .d file. The coverage data file is not created until the program is run. Then one coverage data file is produced as opposed to one file for each module compiled for coverage analysis.
Having compiled index.assist.c, you can run index.assist
% index.assist
By default, the name of the directory where the tcovd file is stored is derived from the name of the executable. Furthermore, that directory is created in the directory the executable was run in (the original tcov created the .d files in the directory where the modules were compiled).
The directory where the tcovd file is stored is also known as the "profile bucket." The profile bucket can be overridden by using the
SUN_PROFDATA
environment variable. This may be useful if the name of the executable is not the same as the value in argv[0] (for example, the invocation of the executable was through a symbolic link with a different name). You can also override the directory where the profile bucket is created. To specify a location different from the run directory, specify the path using the
SUN_PROFDATA_DIR
environment variable.Absolute or relative pathnames can be specified in this variable. Relative pathnames are relative to the program's current working directory at program completion.
TCOVDIR
is supported as a synonym for SUN_PROFDATA_DIR
for backward compatibility. Any setting of SUN_PROFDATA_DIR
causes TCOVDIR
to be ignored. If both SUN_PROFDATA_DIR
and TCOVDIR
are set, a warning is displayed when the profile bucket is generated. SUN_PROFDATA_DIR
takes precedence over TCOVDIR
. The variables are used at runtime by a program compiled with -xprofile=tcov, and are used by the tcov command.
Now that some coverage data has been produced, you can generate a report that relates the raw data back to the source files:
Note - This scheme is also used by the profile feedback mechanism.
% tcov -x index.profile index.assist.c
The output of this report is identical to the one from the previous example (for the original tcov).
% cc -G -xprofile=tcov -o foo.so.1 doo.o
The locking scheme does an exponential back-off if there is a contention for the lock. If, after five tries, the tcov runtime cannot acquire the lock, it gives up and the data is lost for that run. In this case, the following message is displayed:
Compile the program with tcov or Profile Feedback collection turned on, and run the program. At exit, the running program generates a profile bucket. If a previous profile bucket exists, the program uses that profile bucket. If a profile bucket does not exist, it creates the profile bucket.
The default profile bucket the program creates is named after the executable with a ".profile" extension and is created in the place where the executable is run. Therefore, if you are in /home/joe, and run a program called /usr/bin/xyz, the default behavior is to create a profilebucket called xyz.profile in /home/joe.
There are two ways to override the default:
SUN_PROFDATA
.
SUN_PROFDATA_DIR
on the Profile Feedback compile line: absolute pathnames (which start with a `/'), and relative pathnames. If you use an absolute pathname, the profile bucket is dropped into that directory. If you specify a relative pathname, then it is relative to the current working directory where the executable is being run.For example, if you are in /home/joe and run a program called /usr/bin/xyz with
SUN_PROFDATA_DIR
set to .. , then the profile bucket is called /home/joe/../xyz.profile. The value specified in the environment variable was relative, and therefore, it was relative to /home/joe. Also, the default profile bucket name is used, which is named after the executable.The previous version of tcov (enabled by compiling with the
-xa
or -a
flag) used an environment variable called TCOVDIR
. TCOVDIR
specified the directory where the tcov counter files go to instead of next to the source files. We have retained compatibility with this environment variable, in that the new SUN_PROFDATA_DIR
environment variable behaves like the TCOVDIR
environment variable. If both variables are set, a warning is output and SUN_PROFDATA_DIR
takes precedence over TCOVDIR
.
SUN_PROFDATA
Can be used to specify the name of the profile bucket at runtime.The value of this variable is always appended to the value of
SUN_PROFDATA_DIR i
f both variables are set.
SUN_PROFDATA_DIR
Can be used to specify the name of the directory containing the profile bucket. It is used at runtime and in the tcov command.
TCOVDIR
TCOVDIR
is supported as a synonym for SUN_PROFDATA_DIR
to maintain backward compatibility. Any setting of SUN_PROFDATA_DIR
causes TCOVDIR
to be ignored. If both SUN_PROFDATA_DIR
and TCOVDIR
are set, a warning is displayed when the profile bucket is generated.
TCOVDIR
is used at runtime by a program compiled with -xprofile=tcov and it is used by the tcov command.
-xprofile=collect
and -xprofile=use
, you must use the same command-line options.
collect
and use
Profile Feedback phases.
-xprofile=collect
[:
nameopt]
nameopt specifies a name for the generated profile bucket. It is not a path name to the profile bucket, but the actual name. nameopt can name an absolute or relative profile bucket.
If nameopt is not specified, the default output profile bucket is placed in the current working directory. It is given the same name as the executable with a .profile extension.
If nameopt is specified, the profile bucket is called nameopt. If nameopt is a relative pathname to the profile bucket, it is generated relative to the current working directory.
If nameopt is specified, it should be a path to the profile bucket. The compiler does not change the user specified name of the profile bucket. If nameopt is an absolute name, it is used as specified; otherwise nameopt is relative to the current working directory.
If nameopt is specified, the environment variables do not affect it. The compiler uses nameopt as the name of the profile bucket.
-xprofile=use
[:
nameopt]
If nameopt is not specified, the default profile bucket name the compiler uses is a.out.profile in the current working directory.
If nameopt is specified, it should be a path to the profile bucket. The compiler does not change the user specified name of the profile bucket. If nameopt is an absolute name, it is used as specified; otherwise nameopt is relative to the current working directory.
If nameopt is specified, the environment variables do not affect it. The compiler uses nameopt as the name of the profile-bucket.
-xprofile=tcov
-xprofile=collect
and -xprofile=tcov
If you set
SUN_PROFDATA
, the profile bucket is called $SUN_PROFDATA
, wherever it is located.If you set
SUN_PROFDATA_DIR
, the profile bucket is placed in the specified directory.
SUN_PROFDATA
and SUN_PROFDATA_DIR
are independent. If both are specified, the profile bucket name is generated by using SUN_PROFDATA_DIR
to find the profile bucket and, SUN_PROFDATA
is used to name the profile bucket in that directory.A UNIX process can change its current working directory during the execution of a program. The current working directory used to generate the profile bucket is the current working directory of the program at exit. In the rare case where a program actually does change its current working directory during execution, the environment variables can easily control where the profile bucket is generated.
-xprofile=collect:
nameopt
-xprofile-bucket
option specifies the name of the profil -bucket to use for the tcov analysis. SUN_PROFDATA_DIR
or TCOVDIR
are prepended to this argument, if they are set.
SUN_PROFDATA_DIR
to your private directory and leave it set.
SUN_PROFDATA
to the name of a specific profile bucket that will be created, if necessary.
SUN_PROFDATA
to a different name.
SUN_PROFDATA
variable.
-xprofile=collect
. By default, the profile data for each individual program goes into a separate profile bucket, each named after a different executable.
-xprofile=collect
:<my profile-bucket>.
-xprofile=use
:<my profile-bucket> to use this data.
-xprofile=collect
.
% cc -xprofile=collect:/home/bar/run1.profile -o xyz xyz.c -x04
-xprofile=tcov
.
tcov -x xyz.profile filename.c,