MSUTimer
v0.01 alpha
Simple High Resolution Timer for C
|
Despite being usually distributed with MyStr, MSUTimer is stand alone (zero dependencies). It is just a little compliment on the side, for measuring small time-intervals. The source code is available at its own github repository.
This is a toy project really, mostly suitable for quick & dirty time measurements, no more than a few dozens of minutes apart (unless used on Windows). There is no overflow guarding, no special care for multi thread/processor environments, no timing consistency across different platforms.
That said, it's by far more useful & reliable on Windows, under which it was compiled anyway (using MinGW32).
The function msutimer_accuracy_usecs() may be used to get MSUTimer's accuracy in microseconds, at run time.
MSUTimer works best on Windows, due to using directly the native function QueryPerformanceCounter()
. This function gives a resolution less than 1 microsecond, it is not affected by system time changes and processor speeds, and it doesn't roll over for at least 100 years since a system boot.
The POSIX equivalent is clock_gettime(CLOCK_MONOTONIC_RAW)
, but to the best of my knowledge it is still not consistently available across all implementations. Most importantly, currently I don't have easy access to POSIX, so I just used gettimeofday()
instead, which is barely an equivalent. It gets affected by system time changes, with an implementation defined resolution (usually microseconds but not always), but it is available everywhere.
Adding
clock_gettime(CLOCK_MONOTONIC_RAW)
when available, under POSIX, should be fairly easy by checking the preprocessor directive_POSIX_TIMERS
. I'll probably do it, once I'm able to properly test it.
Same goes for macOS, MSSUTimer currently also uses gettimeofday()
when compiled under that OS.
Lastly,clock()
is used as fallback on all other platforms (note that depending on the implementation, this function can roll over as often as every 35 minutes).
Here is the quick summary of the clocking functions picked at compile time, depending on the platform:
QueryPerformanceCounter()
gettimeofday()
clock()
Compilation is pretty straight forward, just make sure you enable C99 support.
There is also an MSUTDEBUG
preprocessor directive, for debugging purposes. When defined with a value of 1, it reports errors on stderr
. When defined with a value of 2 or greater, it additionally stops the execution after reporting an error.
MSDEBUG
may also be used instead ofMSUTDEBUG
(just to stay consistent with MyStr).
To use MSUTimer we can either build it as an object or library file and then link against it, or directly include its files (msutimer.c and msutimer.h) in our project.
After creating a timer with msutimer_new(), the elapsed time between 2 calls of msutimer_gettime() gets auto stored into the timer, in microseconds. It can then be retrieved as a double
with the functions msutimer_diff_secs(), msutimer_diff_msecs() or msutimer_diff_usecs(). They return seconds, milliseconds or microseconds respectively.
Alternatively, the returned double
values of 2 msutimer_gettime() calls can be stored manually by the caller, and then subtracted in order to obtain the time-difference. This is similar to how the standard C function clock()
is used. The macros MSUT_US2MS() or MSUT_US2S() may then be used to convert the calculated difference to milliseconds or seconds, respectively. This manual approach also allows for cumulative timings over multiple calls of msutimer_gettime(), without needing a 2nd timer (see the variable totusecs
in the code snippet below).
When a timer is no longer needed, it should be freed with msutimer_free().
The following code-snippet demonstrates both auto and manual approaches, along with cumulative timing which is manual only (the totusecs
variable):
There are also a few benchmarking functions available, namely:
They all return microseconds as a double
, expecting the piece of code to be timed as a callback function argument. This caller-defined callback function should be of type bool
(C99) returning false
on error, true
otherwise (see the docs of these functions for details). The prototype of the expected callback function is the following:
Here's a full example, timing 50,000,000 square-root calculations of the same random number, in 3 different ways:
MSUtimer is released under the Zlib License.