Timer Function to Provide Time in Nano Seconds Using C++

Timer function to provide time in nano seconds using C++

What others have posted about running the function repeatedly in a loop is correct.

For Linux (and BSD) you want to use clock_gettime().

#include <sys/time.h>

int main()
{
timespec ts;
// clock_gettime(CLOCK_MONOTONIC, &ts); // Works on FreeBSD
clock_gettime(CLOCK_REALTIME, &ts); // Works on Linux
}

For windows you want to use the QueryPerformanceCounter. And here is more on QPC

Apparently there is a known issue with QPC on some chipsets, so you may want to make sure you do not have those chipset. Additionally some dual core AMDs may also cause a problem. See the second post by sebbbi, where he states:

QueryPerformanceCounter() and
QueryPerformanceFrequency() offer a
bit better resolution, but have
different issues. For example in
Windows XP, all AMD Athlon X2 dual
core CPUs return the PC of either of
the cores "randomly" (the PC sometimes
jumps a bit backwards), unless you
specially install AMD dual core driver
package to fix the issue. We haven't
noticed any other dual+ core CPUs
having similar issues (p4 dual, p4 ht,
core2 dual, core2 quad, phenom quad).

EDIT 2013/07/16:

It looks like there is some controversy on the efficacy of QPC under certain circumstances.

...While QueryPerformanceCounter and QueryPerformanceFrequency typically adjust for
multiple processors, bugs in the BIOS or drivers may result in these routines returning
different values as the thread moves from one processor to another...

However this answer states that QPC should work fine on any MS OS after Win XP service pack 2.

Get local time in nanoseconds

Yes, today most hardware supports this sort of resolution, and the C++ standard library has an API that can support it as well. Unfortunately not all implementations of C++ actually do provide it.

The API is the <chrono> library introduced in C++11:

#include <iostream>
#include <chrono>

int main() {
auto start = std::chrono::high_resolution_clock::now();

// operation to be timed ...

auto finish = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(finish-start).count() << "ns\n";
}

The <chrono> implementation in libc++ for Darwin provides nanosecond resolution, but it seems the implementation in VS2012 only goes to tenths of milliseconds. The above code will still give times in terms of nanoseconds, but timings less than 100 microseconds will end up being zero nanoseconds.

Boost also provides an implemenation, boost::chrono, which does seem to use nanoseconds on Windows. It's also usable with C++03.

#include <boost/chrono.hpp>

int main() {
boost::chrono::high_resolution_clock::time_point t1 =
boost::chrono::high_resolution_clock::now();

boost::chrono::high_resolution_clock::time_point t2 =
boost::chrono::high_resolution_clock::now();

std::cout << boost::chrono::duration_cast<boost::chrono::nanoseconds>(t2-t1) << "\n";
// boost chrono has more advanced output, .count() isn't needed, nor is manually writing out the units
}

Custom date and time including nanoseconds

The strftime() function doesn't support sub-second times. You'll need to add that yourself. You also need to use a function that returns sub-second times - that isn't time(). Assuming you have a POSIX-ish system, you can use clock_gettime():

struct timespec tv;
clock_gettime(CLOCK_REALTIME, &tv);
struct tm *timePointerEnd = localtime(&tv.tv_sec);
size_t nbytes = strftime(timeStringEnd, BUFFERSIZE, "\n%B%e, %G %T", timePointerEnd);
snprintf(timeStringEnd + nbytes, sizeof(timeStringEnd) - nbytes,
"%.9ld", tv.tv_nsec);
puts(timeStringEnd);

Note that if you want to print microseconds, you use %.6ld and tm.tv_nsec / 1000; if you want to print milliseconds, you use %.3ld and tm.tv_nsec / 1000000. Care is required.

C11 provides the timespec_get() function that does roughly the same job. It uses a struct timespec, but the arguments are slightly different. You'd pass the pointer first and specify TIME_UTC as the second argument.

If you have neither of those functions available, the (old, obsolescent) POSIX function gettimeofday() provides microsecond resolution timing. And an even older function, ftime(), also from POSIX (but removed from the standard nearly two decades ago) provides millisecond resolution timing. Both of these are often available on non-POSIX systems. Windows has other functions too.

How to obtain nanosecond file creation time in C++

Not all file systems support this (ext4 does):

    struct stat result;
if (stat(filename, &result) == 0) {
printf("Last access of %s: %sns: %ld\n",
filename,
ctime(&result.st_ctim.tv_sec),
result.st_ctim.tv_nsec
);
} else {
fprintf(stderr, "%s: %s.\n", argv[0], strerror(errno));
}


Related Topics



Leave a reply



Submit