Obtaining time difference in nanoseconds - c++

Referring to Obtaining Time in milliseconds
Why does below code produce zero as output?
int main()
{
steady_clock::time_point t1 = steady_clock::now();
//std::this_thread::sleep_for(std::chrono::milliseconds(1500));
steady_clock::time_point t2 = steady_clock::now();
auto timeC = t1.time_since_epoch().count();
auto timeD = t2.time_since_epoch().count();
auto timeA = duration_cast<std::chrono::nanoseconds > ( t1.time_since_epoch()).count();
auto timeB = duration_cast<std::chrono::nanoseconds > ( t2.time_since_epoch()).count();
std::cout << timeC << std::endl;
std::cout << timeB << std::endl;
std::cout << timeD << std::endl;
std::cout << timeA << std::endl;
std::cout << timeB - timeA << std::endl;
system("Pause");
return 0;
}
The output:
14374083030139686
1437408303013968600
14374083030139686
1437408303013968600
0
Press any key to continue . . .
I suppose there should be a difference of few nanoseconds, because of instruction execution time.

Under VS2012, steady_clock (and high_resolution_clock) uses GetSystemTimeAsFileTime, which has a very low resolution (and is non-steady to boot). This is acknowledged as a bug by Microsoft.
Your workaround is to use VS2015, use Boost.Chrono, or implement your own clock using QueryPerformanceCounter (see: https://stackoverflow.com/a/16299576/567292).

Just because you ask it to represent the value in nanoseconds, doesn't mean that the precision of the measurement is in nanoseconds.
When you look at your output you can see that the count are nanoseconds / 100. That that means that the count is representing time in units of 100 nanoseconds.
But even that does not tell you the period of the underlying counter on which steady_clock is built. All you know is it can't be better than 100 nanoseconds.
You can tell the actual period used for the counter by using the periodmember of the steady_clock
double periodInSeconds = double(steady_clock::period::num)
/ double(steady_clock::period::den);
Back to your question: "Why does below code produce zero as output?"
Since you haven't done any significant work between the two calls to now() it is highly unlikely that you have used up 100 nanoseconds, so the answers are the same -- hence the zero.

Related

What precision is used by std::chrono::system_clock?

Here's some code that I found:
std::cout << std::chrono::system_clock::now().time_since_epoch().count() << std::endl;
This prints 1662563612364838407 for me; so it looks like this prints the number of nanoseconds since the UNIX epoch (1970-01-01).
But is this precision guaranteed? I didn't find any indication at https://en.cppreference.com/w/cpp/chrono/system_clock that this value will always be in nanoseconds. Is it possible that this will return e.g. microseconds with another compiler, operating system or hardware?
No it is not guaranteed. You can use the clocks period member alias to get tick period in seconds:
#include <chrono>
#include <iostream>
int main() {
std::cout << std::chrono::system_clock::period::num << " / " << std::chrono::system_clock::period::den;
}
Possible output:
1 / 1000000000
Is it possible that this will return e.g. microseconds with another compiler, operating system or hardware?
Yes, but you can always std::chrono::duration_cast it into a known duration unit. If you want it in seconds for example:
auto dur = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch());
std::cout << dur << '\n';
Possible output:
1662575635s
Pre C++20:
std::cout << dur.count() << '\n';
1662575635
Note: Stay within the chrono domain until it's absolutely necessary to leave it (using .count() etc).

C++ - Time execution 0s with Chrono Library

I'm sorting an array with merge sort. I use the Chrono library to measure the time, but, sometimes, the result is 0.
int main() {
srand(50000);
int A[N];
for (int i = 0; i < N; i++) {
A[i] = rand();
}
cout << "Array non ordinato\n";
Stampa(A, N);
auto start = std::chrono::system_clock::now();
QuickSort(A, 0, N - 1);
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = end - start;
cout << "\nArray ordinato\n";
Stampa(A, N);
cout << "Elapsed time in nanoseconds : "
<< chrono::duration_cast<chrono::nanoseconds>(end - start).count()
<< " ns" << endl;
cout << "Elapsed time in milliseconds : "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count()
<< " ms" << endl;
cout << "Elapsed time: " << elapsed.count() << "s";
}
I defined N with #define N 300.
If N is 300, elapsed time (nanosecond, millisecond or second) is 0. If I increment N, I have an elapsed time greater than zero. I need time for small arrays too. How could I fix it?
If you want more precision for smaller N sorting, I recommend using the high resolution clock instead of the system clock.
When you are measuring time like in the question, you need to use std::chrono::steady_clock or any other clock where the is_steady property is true. std::chrono::system_clock is using the wall-clock which may change at any given time. This is the purpose of the std::chrono::system_clock: to represent the current time for the system.
You probably also want to use a higher number of elements to see any meaningful differences in time.
Although std::chrono::high_resolution clock is tempting going by it's name alone, it is worth noting that there is, technically, no high resolution clock in chrono. Rather, it is an alias to the clock that has the highest resolution available. Quoting from the standard:
Objects of class high_resolution_clock represent clocks with the
shortest tick period. high_resolution_clock may be a synonym for
system_clock or steady_clock.
when we check the implementations we see that MSVC has the following:
using high_resolution_clock = steady_clock;
while libstdc++-v3 has:
/**
* #brief Highest-resolution clock
*
* This is the clock "with the shortest tick period." Alias to
* std::system_clock until higher-than-nanosecond definitions
* become feasible.
*/
using high_resolution_clock = system_clock;

Time measurements with High_resolution_clock not working as intended

I want to be able to measure time elapsed (for frame time) with my Clock class. (Problem described below the code.)
Clock.h
typedef std::chrono::high_resolution_clock::time_point timePt;
class Clock
{
timePt currentTime;
timePt lastTime;
public:
Clock();
void update();
uint64_t deltaTime();
};
Clock.cpp
#include "Clock.h"
using namespace std::chrono;
Clock::Clock()
{
currentTime = high_resolution_clock::now();
lastTime = currentTime;
}
void Clock::update()
{
lastTime = currentTime;
currentTime = high_resolution_clock::now();
}
uint64_t Clock::deltaTime()
{
microseconds delta = duration_cast<microseconds>(currentTime - lastTime);
return delta.count();
}
When I try to use Clock like so
Clock clock;
while(1) {
clock.update();
uint64_t dt = clock.deltaTime();
for (int i=0; i < 10000; i++)
{
//do something to waste time between updates
int k = i*dt;
}
cout << dt << endl; //time elapsed since last update in microseconds
}
For me it prints about 30 times "0" until it finally prints a number which is always very close to something like "15625" microseconds (15.625 milliseconds).
My question is, why isn't there anything between? I'm wondering whether my implementation is wrong or the precision on high_resolution_clock is acting strange. Any ideas?
EDIT: I am using Codeblocks with mingw32 compiler on a windows 8 computer.
EDIT2:
I tried running the following code that should display high_resolution_clock precision:
template <class Clock>
void display_precision()
{
typedef std::chrono::duration<double, std::nano> NS;
NS ns = typename Clock::duration(1);
std::cout << ns.count() << " ns\n";
}
int main()
{
display_precision<std::chrono::high_resolution_clock>();
}
For me it prints: "1000 ns". So I guess high_resolution_clock has a precision of 1 microsecond right? Yet in my tests it seems to have a precision of 16 milliseconds?
What system are you using? (I guess it's Windows? Visual Studio is known to had this problem, now fixed in VS 2015, see the bug report). On some systems high_resolution_clock is defined as just an alias to system_clock, which can have really low resolution, like 16 ms you are seeing.
See for example this question.
I have the same problem with msys2 on Windows 10: the delta returned is 0 for most of my subfunctions tested and suddenly returns 15xxx or 24xxx microseconds. I thought there was a problem in my code as all the tutorials do not mention any problem.
Same thing for difftime(finish, start) in time.h which often returns 0.
I finally changed all my high_resolution clock with steady_clock, and I can find the proper times:
auto t_start = std::chrono::steady_clock::now();
_cvTracker->track(image); // my function to test
std::cout << "Time taken = " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock ::now() - t_start).count() << " microseconds" << std::endl;
// returns the proper value (or at least a plausible value)
whereas this returns mostly 0:
auto t_start = std::chrono::high_resolution_clock::now();
_cvTracker->track(image); // my function to test
std::cout << "Time taken = " << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - t_start).count() << " microseconds" << std::endl;
// returns 0 most of the time
difftime does not seem to work either:
time_t start, finish;
time(&start);
_cvTracker->track(image);
time(&finish);
std::cout << "Time taken= " << difftime(finish, start) << std::endl;
// returns 0 most of the time

C++11 sleep_ functions having odd behaviour

Here it says that sleep_for "Blocks the execution of the current thread for at least the specified sleep_duration."
Here it says that sleep_until "Blocks the execution of the current thread until specified sleep_time has been reached."
So with this in mind I was simply doing my thing, until I noticed that my code was sleeping a lot shorter than the specified time. To make sure it was the sleep_ code being odd instead off me making dumb code again, I created this online example: https://ideone.com/9a9MrC
(code block below the edit line) When running the online example, it does exactly what it should be doing, but running the exact same code sample on my machine gives me this output: Output on Pastebin
Now I'm truly confused and wondering what the bleep is going wrong on my machine. I'm using Code::Blocks as IDE on a Win7 x64 machine in combination with This toolchain containing GCC 4.8.2.
*I have tried This toolchain before the current one, but this one with GCC 4.8.0 strangely enough wasn't even able to compile the example code.
What could create this weird behaviour? My machine? Windows? GCC? Something else in the toolchain?
p.s. The example also works as it should on Here, which states that it uses GCC version 4.7.2
p.p.s. using #include <windows.h> and Sleep( 1 ); also sleeps a lot shorter than the specified 1 millisecond on my machine.
EDIT: code from example:
#include <iostream> // std::cout, std::fixed
#include <iomanip> // std::setprecision
//#include <string> // std::string
#include <chrono> // C++11 // std::chrono::steady_clock
#include <thread> // C++11 // std::this_thread
std::chrono::steady_clock timer;
auto startTime = timer.now();
auto endTime = timer.now();
auto sleepUntilTime = timer.now();
int main() {
for( int i = 0; i < 10; ++i ) {
startTime = timer.now();
sleepUntilTime = startTime + std::chrono::nanoseconds( 1000000 );
std::this_thread::sleep_until( sleepUntilTime );
endTime = timer.now();
std::cout << "Start time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( startTime.time_since_epoch() ).count() << "\n";
std::cout << "End time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime.time_since_epoch() ).count() << "\n";
std::cout << "Sleep till: " << std::chrono::duration_cast<std::chrono::nanoseconds>( sleepUntilTime.time_since_epoch() ).count() << "\n";
std::cout << "It took: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() << " nanoseconds. \n";
std::streamsize prec = std::cout.precision();
std::cout << std::fixed << std::setprecision(9);
std::cout << "It took: " << ( (float) std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() / 1000000 ) << " milliseconds. \n";
std::cout << std::setprecision( prec );
}
std::cout << "\n\n";
for( int i = 0; i < 10; ++i ) {
startTime = timer.now();
std::this_thread::sleep_for( std::chrono::nanoseconds( 1000000 ) );
endTime = timer.now();
std::cout << "Start time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( startTime.time_since_epoch() ).count() << "\n";
std::cout << "End time: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime.time_since_epoch() ).count() << "\n";
std::cout << "It took: " << std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() << " nanoseconds. \n";
std::streamsize prec = std::cout.precision();
std::cout << std::fixed << std::setprecision(9);
std::cout << "It took: " << ( (float) std::chrono::duration_cast<std::chrono::nanoseconds>( endTime - startTime ).count() / 1000000 ) << " milliseconds. \n";
std::cout << std::setprecision( prec );
}
return 0;
}
Nothing is wrong with your machine, it is your assumptions that are wrong.
Sleeping is a very system-dependent and unreliable thing. Generally, on most operating systems, you have a more-or-less-guarantee that a call to sleep will delay execution for at least the time you ask for. The C++ thread library necessarily uses the facilities provided by the operating system, hence the wording in the C++ standard that you quoted.
You will have noted the wording "more-or-less-guarantee" in the above paragraph. First of all, the way sleeping works is not what you might think. It generally does not block until a timer fires and then resumes execution. Instead, it merely marks the thread as "not ready", and additionally does something so this can be undone later (what exactly this is isn't defined, it might be setting a timer or something else).
When the time is up, the operating system will set the thread to "ready to run" again. This doesn't mean it will run, it only means it is a candidate to run, whenever the OS can be bothered and whenever a CPU core is free (and nobobdy with higher priority wants it).
On traditional non-tickless operating systems, this will mean that the thread will probably (or more precisely, maybe) run at the next scheduler tick. That is, if CPU is available at all. On more modern operating systems (Linux 3.x or Windows 8) which are "tickless", you're a bit closer to reality, but you still do not have any hard guarantees.
Further, under Unix-like systems, sleep may be interrupted by a signal and may actually wait less than the specified time. Also, under Windows, the interval at which the scheduler runs is configurable, and to make it worse, different Windows versions behave differently [1] [2] in respect of whether they round the sleep time up or down.
Your system (Windows 7) rounds down, so indeed yes, you may actually wait less than what you expected.
tl;dr
Sleep is unreliable and only a very rough "hint" (not a requirement) that you wish to pass control back to the operating system for some time.

Measuring time results in return values of 0 or 0.001

I am trying to use chrono::steady_clock to measure fractional seconds elapsed between a block of code in my program. I have this block of code working in LiveWorkSpace (http://liveworkspace.org/code/YT1I$9):
#include <chrono>
#include <iostream>
#include <vector>
int main()
{
auto start = std::chrono::steady_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = std::chrono::steady_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
std::cout << "seconds since start: " << ((double)difference / 1000000);
}
When I implement the same idea into my program like so:
auto start = std::chrono::steady_clock::now();
// block of code to time
auto end = std::chrono::stead_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
std::cout << "seconds since start: " << ((double) difference / 1000000);
The program will only print out values of 0 and 0.001. I highly doubt that the execution time for my block of code always equals 0 or 1000 microseconds, so what is accounting for this rounding and how might I eliminate it so that I can get the proper fractional values?
This is a Windows program.
This question already has a good answer. But I'd like to add another suggestion:
Work within the <chrono> framework. Build your own clock. Build your own time_point. Build your own duration. The <chrono> framework is very customizable. By working within that system, you will not only learn std::chrono, but when your vendor starts shipping clocks you're happy with, it will be trivial to transition your code from your hand-rolled chrono::clock to std::high_resolution_clock (or whatever).
First though, a minor criticism about your original code:
std::cout << "seconds since start: " << ((double) difference / 1000000);
Whenever you see yourself introducing conversion constants (like 1000000) to get what you want, you're not using chrono correctly. Your code isn't incorrect, just fragile. Are you sure you got the right number of zeros in that constant?!
Even in this simple example you should say to yourself:
I want to see output in terms of seconds represented by a double.
And then you should use chrono do that for you. It is very easy once you learn how:
typedef std::chrono::duration<double> sec;
sec difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
The first line creates a type with a period of 1 second, represented by a double.
The second line simply subtracts your time_points and assigns it to your custom duration type. The conversion from the units of steady_clock::time_point to your custom duration (a double second) are done by the chrono library automatically. This is much simpler than:
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
And then finally you just print out your result with the .count() member function. This is again much simpler than:
std::cout << "seconds since start: " << ((double) difference / 1000000);
But since you're not happy with the precision of std::chrono::steady_clock, and you have access to QueryPerformanceCounter, you can do better. You can build your own clock on top of QueryPerformanceCounter.
<disclaimer>
I don't have a Windows system to test the following code on.
</disclaimer>
struct my_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock> time_point;
static const bool is_steady = false;
static time_point now()
{
static const long long frequency = init_frequency();
long long t;
QueryPerformanceCounter(&t);
return time_point(duration(static_cast<rep>(t)/frequency));
}
private:
static long long init_frequency()
{
long long f;
QueryPerformanceFrequency(&f);
return f;
}
};
Since you wanted your output in terms of a double second, I've made the rep of this clock a double and the period 1 second. You could just as easily make the rep integral and the period some other unit such as microseconds or nanoseconds. You just adjust the typedefs and the conversion from QueryPerformanceCounter to your duration in now().
And now your code can look much like your original code:
int main()
{
auto start = my_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = my_clock::now();
auto difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
}
But without the hand-coded conversion constants, and with (what I'm hoping is) sufficient precision for your needs. And with a much easier porting path to a future std::chrono::steady_clock implementation.
<chrono> was designed to be an extensible library. Please extend it. :-)
After running some tests on MSVC2012, I could confirm that the C++11 clocks in Microsoft's implementation do not have a high enough resolution. See C++ header's high_resolution_clock does not have high resolution for a bug report concerning this issue.
So, unfortunately for a higher resolution timer, you will need to use boost::chrono or QueryPerformanceCounter directly like so until they fix the bug:
#include <iostream>
#include <Windows.h>
int main()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER start;
QueryPerformanceCounter(&start);
// Put code here to time
LARGE_INTEGER end;
QueryPerformanceCounter(&end);
// for microseconds use 1000000.0
double interval = static_cast<double>(end.QuadPart- start.QuadPart) /
frequency.QuadPart; // in seconds
std::cout << interval;
}