thegreatjedi
thegreatjedi

Reputation: 3038

How can I measure sub-second durations?

In my calculator-like program, the user selects what and how many to compute (eg. how many digits of pi, how many prime numbers etc.). I use time(0) to check for the computation time elapsed in order to trigger a timeout condition. If the computation completes without timeout, I will also print the computation time taken, the value of which is stored in a double, the return type of difftime().

I just found out that the time values calculated are in seconds only. I don't want a user input of 100 and 10000 results to both print a computation duration of 0e0 seconds. I want them to print, for example, durations of 1.23e-6 and 4.56e-3 seconds respectively (as accurate as the machine can measure - I am more acquainted to the accuracy provided in Java and with the accuracies in scientific measurements so it's a personal preference).

I have seen the answers to other questions, but they don't help because 1) I will not be multi-threading (not preferred in my work environment). 2) I cannot use C++11 or later.

How can I obtain time duration values more accurate than seconds as integral values given the stated constraints?

Edit: Platform & machine-independent solutions preferred, otherwise Windows will do, thanks!

Edit 2: My notebook is also not connected to the Internet, so no downloading of external libraries like Boost (is that what Boost is?). I'll have to code anything myself.

Upvotes: 2

Views: 314

Answers (3)

Puddler
Puddler

Reputation: 2939

You can use QueryPerformanceCounter (QPC) which is part of the Windows API to do high-resolution time measurements.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Upvotes: 3

Matteo Italia
Matteo Italia

Reputation: 126957

On Windows, the simplest solution is to use GetTickCount, which returns the number of milliseconds since the computer was started.

#include <windows.h>

... 

DWORD before = GetTickCount();
... 
DWORD duration = GetTickCount() - before;
std::cout<<"It took "<<duration<<"ms\n";

Caveats:

  • it works only on Windows;
  • the resolution (milliseconds) is not stellar;
  • given that the result is a 32 bit integer, it wraps around after one month or something; thus, you cannot measure stuff longer than that; a possible solution is to use GetTickCount64, which however is available only from Vista onwards;
  • since systems with the uptime of more than one month are actually quite common, you may indeed have to deal with results bigger than 231; thus, make sure to always keep such values in a DWORD (or an uint32_t), without casting them to int, or you are risking signed integer overflow. Another option is to just store them in a 64 bit signed integer (or a double) and forget the difficulties of dealing with unsigned integers.

Upvotes: 2

Jason
Jason

Reputation: 3917

I realize the compiler you're using doesn't support it, but for reference purposes the C++11 solution is simple...

auto start = std::chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();

long ts = std::chrono::duration<long, std::chrono::nano>(end - start).count();

Upvotes: 1

Related Questions