C++11 sleep_ functions having odd behaviour - c++

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.

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++ elapsed time = 0

I have a code written in C++ in Visual Studio:
auto start = std::chrono::high_resolution_clock::now();
result = function(-1, 1, 9999999);
auto end = std::chrono::high_resolution_clock::now();
double time_taken = chrono::duration_cast<chrono::microseconds>(end - start).count();
time_taken *= 1e-6;
std::cout << "result: " << result << "time : " << fixed << time_taken << setprecision(6) << " sec" << endl;
The problem is: I run the code in Release mode and time_taken always equals 0. When I switch to the Debug mode time_taken is between 1 and 2 seconds. I tried different ways to pinpoint time but time_taken always equals 0. How can I fix this?
Thanks in advance for your help!
Apparently you are lacking clock resolution. Or the function was partly or fully optimized away.
Generally it is not trivial to profile small functions.
One thing you should do is to call it a lot of times, and measure time of whole run, then divide this time by number of calls.
Also make sure the function is actually fully computed at runtime by stroing result in a volatile variable, and taking input from volatile variables.

Timing Functions: Double Returning 0 MS

I am writing an in-depth test program for a data structure I had to write for a class. I am trying to time how long it takes functions to execute and store them in an array for later printing. To double check that it was working I decided to print it immediately, and I found out it is not working.
Here is the code where I get the times and store them in an array that is in a struct.
void test1(ArrayLinkedBag<ItemType> &bag,TestAnalytics &analytics){
clock_t totalStart;
clock_t incrementalStart;
clock_t stop; //Both timers stop at the same time;
// Start TEST 1
totalStart = clock();
bag.debugPrint();
cout << "Bag Should Be Empty, Checking..." << endl;
incrementalStart = clock();
checkEmpty<ItemType>(bag);
stop = clock();
analytics.test1Times[0] = analytics.addTimes(incrementalStart,stop);
analytics.test1Times[1] = analytics.addTimes(totalStart,stop);
cout << analytics.test1Times[0] << setprecision(5) << "ms" << endl;
std::cout << "Time: "<< setprecision(5) << (stop - totalStart) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
cout << "===========================================" << endl; //So I can find the line easier
}
Here is the code where I am doing the calculation that I am putting in the array, this function is located in a TestAnalytics struct
double addTimes(double start, double stop){
return (stop - start)/ (double)(CLOCKS_PER_SEC/1000);
}
Here is a snippet of the output I am getting:
Current Head: -1
Current Size: 0
Cell: 1, Index: 0, Item: 6317568, Next Index: -2
Cell: 2, Index: 1, Item: 4098, Next Index: -2
Cell: 3, Index: 2, Item: 6317544, Next Index: -2
Cell: 4, Index: 3, Item: -683175280, Next Index: -2
Cell: 5, Index: 4, Item: 4201274, Next Index: -2
Cell: 6, Index: 5, Item: 6317536, Next Index: -2
Bag Should Be Empty, Checking...
The Bag Is Empty
0ms
Time: 0 ms
===========================================
I am trying to calculate the time as per a different post on this site.
I am using clang compiler on an UNIX system. Is it possible that the number is still too small to show above 0?
Unless you're stuck with an old (pre-C++ 11) compiler/library, I'd use the functions from the <chrono> header:
template <class ItemType>
void test1(ArrayLinkedBag<ItemType> &bag){
using namespace std::chrono;
auto start = high_resolution_clock::now();
bag.debugPrint();
auto first = high_resolution_clock::now();
checkEmpty(bag);
auto stop = high_resolution_clock::now();
std::cout << " first time: " << duration_cast<microseconds>(first - start).count() << " us\n";
std::cout << "second time: " << duration_cast<microseconds>(stop - start).count() << " us\n";
}
Some parts are a bit verbose (to put it nicely) but it still works reasonably well. duration_cast supports difference types down to (at least) nanoseconds, which is typically sufficient for timing even relatively small/fast pieces of code (though it's not guaranteed that it uses a timer with nanosecond precision).
In addition to Jerry's good answer (which I've upvoted), I wanted to add just a little more information that might be helpful.
For timing I recommend steady_clock over high_resolution_clock because steady_clock is guaranteed to not be adjusted (especially backwards) during your timing. Now on Visual Studio and clang, this can't possibly happen because high_resolution_clock and steady_clock are exactly the same type. However if you're using gcc, high_resolution_clock is the same type as system_clock, which is subject to being adjusted at any time (say by an NTP correction).
But if you use steady_clock, then on every platform you have a stop-watch-like timer: Not good for telling you the time of day, but not subject to being corrected at an inopportune moment.
Also, if you use my free, open-source, header-only <chrono> extension library, it can stream out durations in a much more friendly manner, without having to use duration_cast nor .count(). It will print out the duration units right along with the value.
Finally, if you call steady_clock::now() multiple times in a row (with nothing in between), and print out that difference, then you can get a feel for how precisely your implementation is able to time things. Can it time something as short as femtoseconds? Probably not. Is it as coarse as milliseconds? We hope not.
Putting this all together, the following program was compiled like this:
clang++ test.cpp -std=c++14 -O3 -I../date/include
The program:
#include "date/date.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using date::operator<<;
for (int i = 0; i < 100; ++i)
{
auto t0 = steady_clock::now();
auto t1 = steady_clock::now();
auto t2 = steady_clock::now();
auto t3 = steady_clock::now();
auto t4 = steady_clock::now();
auto t5 = steady_clock::now();
auto t6 = steady_clock::now();
std::cout << t1-t0 << '\n';
std::cout << t2-t1 << '\n';
std::cout << t3-t2 << '\n';
std::cout << t4-t3 << '\n';
std::cout << t5-t4 << '\n';
std::cout << t6-t5 << '\n';
}
}
And output for me on macOS:
150ns
80ns
69ns
53ns
63ns
64ns
88ns
54ns
66ns
66ns
59ns
56ns
59ns
69ns
76ns
74ns
73ns
73ns
64ns
60ns
58ns
...

c++ code execution timer returning 0, need output in milliseconds

I'm trying to figure out how to time the execution of part of my program, but when I use the following code, all I ever get back is 0. I know that can't be right. The code I'm timing recursively implements mergesort of a large array of ints. How do I get the time it takes to execute the program in milliseconds?
//opening input file and storing contents into array
index = inputFileFunction(inputArray);
clock_t time = clock();//start the clock
//this is what needs to be timed
newRecursive.mergeSort(inputArray, 0, index - 1);
//getting the difference
time = clock() - time;
double ms = double(time) / CLOCKS_PER_SEC * 1000;
std::cout << "\nTime took to execute: " << std::setprecision(9) << ms << std::endl;
You can use the chrono library in C++11. Here's how you can modify your code:
#include <chrono>
//...
auto start = std::chrono::steady_clock::now();
// do whatever you're timing
auto end = std::chrono::steady_clock::now();
auto durationMS = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "\n Time took " << durationMS.count() << " ms" << std::endl;
If you're developing on OSX, this blog post from Apple may be useful. It contains code snippets that should give you the timing resolution you need.

Obtaining time difference in nanoseconds

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.