gprof Primer
gprof is a useful profiling utility to help speed up your program by telling how how many calls to each function and how long each call lasts.
If you’re on a Linux machine you already have gprof installed, and can always refer to the man pages for more info.
The concise version:
- When compiling code use the -pg option.
- Run the program piping input and output.
- Run gprof to analyze the results.
g++ main.cpp -o main.app -pg -O2
./main.app <in >/dev/null
gprof ./main.app
More after the break.
Modifying Code:
Since gprof only shows the time spent in each function call, it may be necessary for you to break down a time intensive function into multiple subroutines to get a better idea of what is taking the most time.
For example if my original code was:
void foo() {
//normal code
}
For better information I would need to break out the logic as such:
void logic1() { ... }
void logic2() { ... }
void logic3() { ... }
void foo() {
logic1();
logic2();
logic3();
}
However, subroutines will add an additional activation frame per call, slowing your program down during regular compile. As such, you would only want to break out the logic during profiling. You can get around this using macros.
#ifdef PROFILE
void logic1() { ... }
void logic2() { ... }
void logic3() { ... }
#endif
void foo() {
#ifdef PROFILE
logic1();
logic2();
logic3();
#else
//normal code
#endif
}
One last alternative is to specify the use of an inline function toggled by a macro, but this action may already be automatically performed at a high level optimization option.
Compile:
The -pg option during compile will create gmon.out which is used by gprof to profile the code. If the code is separated with the above modifications, include -DPROFILE.
One last thing of note is to use the correct optimization flag that will be used in the final release. If not, then developer time may be wasted spent optimizing certain parts of the code that are already handled by the compiler.
Thus are modified compile command ends up looking like:
g++ main.cpp -o main.app -pg -O2 -DPROFILE
Run:
At this point run the program, piping input and output in order to slow down the program as little as possible. For most accurate results, use a large enough input to run the program for 30 - 60 seconds.
./main.app < in >/dev/null 2>&1
After running the program, a file called gmon.out is created.
Analyze:
To analyze the results run gprof which uses the results saved in gmon.out. Given the verbosity, it may be useful to pipe the output to an editor or pager.
gprof ./main.app | less
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls us/call us/call name 97.63 23.47 23.47 14308586 1.64 1.64 isprime_naive(int const&) 0.71 23.64 0.17 25382561 0.01 0.01 isprime(int const&) 0.50 23.76 0.12 25145678 0.00 0.00 isprime_edge_cases(int const&) 0.37 23.85 0.09 2999999 0.03 0.03 print(std::ostream&) 0.25 23.91 0.06 2999998 0.02 7.94 find_sum(int const&) 0.21 23.96 0.05 2999999 0.02 7.96 eval() 0.17 24.00 0.04 3000000 0.01 0.01 read(std::istream&) 0.17 24.04 0.04 main 0.00 24.04 0.00 1 0.00 0.00 global constructors keyed to in 0.00 24.04 0.00 1 0.00 0.00 build_primes()
A detailed explanation on how to read the results can be found here in addition to gprof’s output, but the output should be fairly self-explanatory. Focus should be spent on which function calls take up the highest percentage of cumulative time and improvements can most likely be found in functions with a high self ms/call.
Last Words:
gprof is a highly useful utility that can help a developer determine what is causing a program’s slowdown, but there is a danger of overly micro-optimizing when it’s possible to have larger speed improvements at a higher logic level (e.g. choosing better data structures, algorithms).


[...] always talks about profiling, but Ting actually does it. Here’s a great blog post on using gprof, I’ll definitely start profiling my apps beginning with the next project. Per Dustin, [...]
Benry’s CS 371P Blog » Blog Archive » Thoughts on CS 371P, Week 3 said this on September 12, 2009 at 6:17 pm