A while back I wrote a post about how I’ve used Stopwatch to profile .NET applications, this post is similar, it shows how “micro-benchmarking” can be done in C++ and more importantly it also shows how we can create a “using block” in C++.
Igal T. has written an excellent post on how to analyze the results using Excel.
The unmanaged Stopwatch
Benchmarking in C++ can be done using the following code (courtesy of Igal T):
The performance counter is very simple –
- it has two static methods – Start and End (lines 13-14)
- A Stack of LARGE_INTEGER (line 9)
The implementation is also very simple – as long as you know your WinAPI:
When Start called:
- Get the current performance count (line 8-9)
- Shove the value into the stack (line 10)
When End is called:
- Get the current performance count (line 15-16)
- Get the frequency (17-18) – this can be done only once
- Get the topmost value from the counter stack (line 20)
- Calculate the seconds passed between when start was called till now (lines 22-23)
- Mix and print (lines 24 – 26)
Note: The only problem with this approach is that you must make sure that your code runs on the same processor throughout the application execution – otherwise you might get very weird results. So either run your benchmark on a single processor machine or set processor affinity either by code or from task manager.
What about “Using”
The Performancer class is simple to use and it supports nested class to Start but there is still something missing, in the .NET example I’ve used IDisposable and Using to make my life easier by “automatically” calling the End method. C++ does not have IDisposable but it does have destructors that can be used in the same way.
First let’s update the Performancer class:
Because we’re only need one of these per call – I’ve removed the stack.
Now for the interesting part – I present before you my interpretation of Stopwatch:
For simplicity stake I’ve written the implementation in the header file – please don’t do that in any C++ project I might need to work on 😉
So what do we have here:
- Two fields – an instance of old trusty Performancer and the method’s name (3-4)
- A private c’tor that receives a method name and call Start (6-9)
- A d’tor that calls End (11-14)
- A static Create method that makes everything “tick”
How do I use it?
Just call StopWatch::Create to start counting and the counter will stop working when you go out of scope and the destructor will get called. It also means that you need to store Stopwatch instance in some variable like so: