24 September 2008

Counting and profiling

You can make gcc tell you how many times each line in your program is executed! This is useful for profiling (since it gives insight into where the program lingers), for optimising (since gcc can use the results to generate better assembly), and for testing (since you can see if there are lines not covered by your tests). So it's pretty useful.

How? Read on. Here's a program to illustrate:

#include <algorithm>
#include <iostream>
#include <limits>
#include <vector>

using namespace std;

const int n = 10;

int maximum(const vector<int>& v) {
  int r = numeric_limits<int>::min();
  for (int i = 0; i < v.size(); ++i) {
    if (v[i] > r)
      r = v[i];
  }
  return r;
}

int main() {
  vector<int> v(n);
  for (int i = 0; i < n; ++i) v[i] = i;
  int sum = 0;
  do {
    sum += maximum(v);
  } while (next_permutation(v.begin(), v.end()));
  cout << sum << endl;
  return 0;
}

Now compile, run, generate line counts:

g++ -fprofile-arcs -ftest-coverage a.cpp
./a.out
gcov a

Take a look at the result:

        -:    0:Source:a.cpp
        -:    0:Graph:a.gcno
        -:    0:Data:a.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include <algorithm>
        -:    2:#include <iostream>
        -:    3:#include <limits>
        -:    4:#include <vector>
        -:    5:
        -:    6:using namespace std;
        -:    7:
        -:    8:const int n = 10;
        -:    9:
  3628800:   10:int maximum(const vector<int>& v) {
  3628800:   11:  int r = numeric_limits<int>::min();
 39916800:   12:  for (int i = 0; i < v.size(); ++i) {
 36288000:   13:    if (v[i] > r)
 10628640:   14:      r = v[i];
        -:   15:  }
  3628800:   16:  return r;
        -:   17:}
        -:   18:
        1:   19:int main() {
        1:   20:  vector<int> v(n);
        1:   21:  for (int i = 0; i < n; ++i) v[i] = i;
        1:   22:  int sum = 0;
  3628800:   23:  do {
  3628800:   24:    sum += maximum(v);
        -:   25:  } while (next_permutation(v.begin(), v.end()));
        1:   26:  cout << sum << endl;
        1:   27:  return 0;
        1:   28:}
        1:   29:/*EOF*/

In theory, you can now do:

g++ -fprofile-arcs -ftest-coverage -fbranch-probabilities a.cpp

No comments:

Post a Comment

Note: (1) You need to have third-party cookies enabled in order to comment on Blogger. (2) Better to copy your comment before hitting publish/preview. Blogger sometimes eats comments on the first try, but the second works. Crazy Blogger.