Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with heavy profiling of execution times in C++

I'm currently working on a scientific computing project involving huge data and complex algorithms, so I need to do a lot of code profiling. I'm currently relying on <ctime> and clock_t to time the execution of my code. I'm perfectly happy with this solution... except that I'm basically timing everything and thus for every line of real code I have to call start_time_function123 = clock(), end_time_function123 = clock() and cout << "function123 execution time: " << (end_time_function123-start_time_function123) / CLOCKS_PER_SEC << endl. This leads to heavy code bloating and quickly makes my code unreadable. How would you deal with that?

The only solution I can think of would be to find an IDE allowing me to mark portions of my code (at different locations, even in different files) and to toggle hide/show all marked code with one button. This would allow me to hide the part of my code related to profiling most of the time and display it only whenever I want to.

like image 708
Adrien Avatar asked Feb 25 '17 14:02

Adrien


2 Answers

Have a RAII type that marks code as timed.

struct timed {
  char const* name;
  clock_t start;
  timed( char const* name_to_record):
    name(name_to_record),
    start(clock())
  {}
  ~timed(){
    auto end=clock();
    std::cout << name << " execution time: " << (end-start) / CLOCKS_PER_SEC << std::endl;
  }
};

The use it:

void foo(){
  timed timer(__func__);
  // code
}

Far less noise.

You can augment with non-scope based finish operations. When doing heavy profiling sometimes I like to include unique ids. Using cout esoecially with endl could result in it dominating timing; fast recording to a large buffer that is dumped out in an async manner may be optimal. If you need to time ms level time, even allocation, locks and string manipulation should be avoided.

like image 170
Yakk - Adam Nevraumont Avatar answered Sep 29 '22 11:09

Yakk - Adam Nevraumont


You don't say so explicitly, but I assume you are looking for possible speedups - ways to reduce the time it takes.

You think you need to do this by measuring how much time different parts of it take. If you're interested, there's an orthogonal way to approach it.

Just get it running under a debugger (using a non-optimized debug build). Manually interrupt it at random, by Ctrl-C, Ctrl-Break, or the IDE's "pause" button. Display the call stack and carefully examine what the program is doing, at all levels.

Do this with a suspicion that whatever it's doing could be something wasteful that you could find a better way to do.

Then if you start it up again, and halt it again, and see it doing the same thing or something similar, you know you will get a substantial speedup if you fix it. The fewer samples you took to see that thing twice, the more speedup you will get.

That's the random pausing technique, and the statistical rationale is here. The reason you do it on a debug build is here. After you've cut out the fat using this method, you can switch to an optimized build and get the extra margin it gives you.

like image 43
Mike Dunlavey Avatar answered Sep 29 '22 11:09

Mike Dunlavey