gprof - A GNU Profiler For Performance Analysis Of Programs

October 17, 2013 | By
| Reply More

In the software industry today, performance of a software has become the most important requirement. Software programmers and developers are trying harder than ever to improve the performance of their respective software. A well written software code consists of various functions. As the code becomes larger and larger, the number of functions and nested function calls also increase. So, to analyse the performance of such a program, it becomes necessary to understand which functions are taking time to execute. Also, individual function analysis should also provide clear distinguishing between the time taken by the parent function and the other functions called from within the parent function.

Software tools that are used for this kind of performance analysis are popularly known as profilers. In this article, we will discuss a Linux based profiler -- gprof.

NOTE - All the examples presented in this article are tested on Ubuntu 13.04, bash 4.2.45 and gprof 2.23.2.

Gprof Setup & Usage

Here are some of the steps required for downloading and setting environment for gprof :

  • If not installed already, download and install gprof by executing apt-get install binutils
  • To check that gprof is installed properly, execute the gprof command and it should give some error like a.out: No such file or directory.
  • Assuming that the compiler being used it gcc or cc, compile your code with the option -pg so that the executable includes extra code for profiling purpose.
  • Run the program in a normal way. When the program terminates, a file named gmon.out (profiler data) would be produced in the same directory from which the program was run.
  • Use the gprof profiler to process this profiler data (gmon.out) and produce human readable performance analysis and statistics of the program.

An Example

Here is an example code that we want to profile :

#include<stdio.h>

void some_other_test(void)
{
printf("\n Inside the function some_other_test() \n");
int i = 0;
for(;i<=0XFFFF;i++);
}

void yet_another_test(void)
{
printf("\n Inside the function yet_other_test() \n");
int i = 0;
for(;i<=0XFFFFFFF;i++);
}

void another_test(void)
{
printf("\n Inside the function another_test() \n");
int i = 0;
for(;i<=0XFFF;i++);

yet_another_test();
}

void test(void)
{
printf("\n Inside the function test() \n");
int i = 0;
for(;i<=0XFFFFFF;i++);

another_test();
}

int main(void)
{
printf("\n Inside the function main() \n");
int i = 0;
for(;i<=0XFFFFF;i++);

test();
some_other_test();

return 0;
}

Note that the code above is just a dummy example that contains for loops to simulate time consumption in function processing.

Once the code is in place, the first step is to compile the code. Here is how you can do it :

$ gcc -Wall -pg profile.c -o profile

So you can see that the code was saved in a file named profile.c and the output file name is profile.

Once the executable named profile was produced, it was executed like any other program :

$ ./profile

Inside the function main()

Inside the function test()

Inside the function another_test()

Inside the function yet_other_test()

Inside the function some_other_test()

So you can see that the program executed successfully. Also, it produced a file named gmon.out in the same directory.

$ ls gmon.out
gmon.out

Now, use the gprof utility in the following way :

$ gprof profile gmon.out > output

So you can see that the executable name and gmon.out were provided as arguments to gprof command and the output was redirected to a file named output. This file contains all the statistical analysis of the performance of the program profile in human readable form.

The contents of output are divided into types of information -- Flat profile and Call graph.

Flat Profile

Here is the statistical analysis in form of flat profile :

gprof statistical analysis

The statistics displayed above is known as flat profile. Here is the explanation (taken from the file output) of what each column means :

  • % time - The percentage of the total running time of the program used by this function.
  • Cumulative seconds - A running sum of the number of seconds accounted for by this function and those listed above it.
  • Self seconds - The number of seconds accounted for by this function alone.  This is the major sort for this listing.
  • Calls - The number of times this function was invoked, if this function is profiled, else blank.
  • Self ms/call - The average number of milliseconds spent in this function per call, if this function is profiled, else blank.
  • Total ms/call - The average number of milliseconds spent in this function and its descendent per call, if this function is profiled, else blank.
  • Name - The name of the function.  This is the minor sort for this listing. The index shows the location of the function in the gprof listing. If the index is in parenthesis it shows where it would appear in the gprof listing if it were to be printed.

Call Graph

Here is the statistical analysis in form of a call graph :

gprof statistical analysis call graph

This table describes the call tree of the program, and was sorted by the total amount of time spent in each function and its children. Each entry in this table consists of several lines. The line with the  index number at the left hand margin lists the current function. The lines above it list the functions that called this function, and the lines below it list the functions this one called.

Here is the explanation (taken from the file output) of what each column means:

  • Index - A unique number given to each element of the table. Index numbers are sorted numerically. The index number is printed next to every function name so it is easier to look up where the function is in the table.
  • % time - This is the percentage of the `total' time that was spent in this function and its children.  Note that due to different viewpoints, functions excluded by options, etc., these numbers will NOT add up to 100%.
  • Self  - This is the total amount of time spent in this function. For function's parents, this is the amount of time that was propagated directly from the function into this parent. While, for function's children, this is the amount of time that was propagated directly from the child into the function.
  • Children - This is the total amount of time propagated into this function by its children. For the function's parents, this is the amount of time that was propagated from the function's children into this parent. While, for the function's children, this is the amount of time that was propagated from the child's children to the function.
  • Called - This is the number of times the function was called. If the function called itself recursively, the number only includes non-recursive calls, and is followed by a `+' and the number of recursive calls. For the function's parents, this is the number of times this parent called the function `/' the total number of times the function was called. Recursive calls to the function are not included in the number after the `/'. While, for the function's children, this is the number of times the function called this child `/' the total number of times the child was called. Recursive calls by the child are not listed in the number after the `/'.
  • Name - The name of the current function. The index number is printed after it.  If the function is a member of a cycle, the cycle number is printed between the function's name and the index number. For function's parents, this is the name of the parent. The parent's index number is printed after it. If the parent is a member of a cycle, the cycle number is printed between the name and the index number. For function's children, this is the name of the child. The child's index number is printed after it. If the child is a member of a cycle, the cycle number is printed between the name and the index number.

NOTE - All the explanation mentioned above is also present in the output file generated by gprof. I have mentioned it here for the ease of readers.

NOTE - All this explanation is produced in the output file every-time gprof is run. So, once you've understood the details, you can use the gprof command line option -b. To read about more command line options, read gprof man page.

Filed Under : OPEN SOURCE TOOLS

Free Linux Ebook to Download

Leave a Reply

Commenting Policy:
Promotion of your products ? Comment gets deleted.
All comments are subject to moderation.