If I put two calls side-by-side to determine the smallest measurable time duration:
// g++ -std=c++11 -O3 -Wall test.cpp
#include <chrono>
typedef std::chrono::high_resolution_clock hrc;
hrc::time_point start = hrc::now();
hrc::time_point end = hrc::now();
std::chrono::nanoseconds duration = end - start;
std::cout << "duration: " << duration.count() << " ns" << std::endl;
I've run this thousands of times in a loop, and I consistently get 40 ns +/- 2 ns on my particular 3.40GHz desktop.
However, when I look to see what is the shortest time I can sleep:
#include <thread>
hrc::time_point start = hrc::now();
std::this_thread::sleep_for( std::chrono::nanoseconds(1) );
hrc::time_point end = hrc::now();
std::chrono::nanoseconds duration = end - start;
std::cout << "slept for: " << duration.count() << " ns" << std::endl;
This tells me I slept on average 55400 nanoseconds, or 55.4 microseconds. Much greater than the time I expected.
Putting the above code into a for()
loop, I tried sleeping for different amounts, and this is the result:
- sleep_for( 4000 ns ) => slept for 58000 ns
- sleep_for( 3000 ns ) => slept for 57000 ns
- sleep_for( 2000 ns ) => slept for 56000 ns
- sleep_for( 1000 ns ) => slept for 55000 ns
- sleep_for( 0 ns ) => slept for 54000 ns
- sleep_for( -1000 ns ) => slept for 313 ns
- sleep_for( -2000 ns ) => slept for 203 ns
- sleep_for( -3000 ns ) => slept for 215 ns
- sleep_for( -4000 ns ) => slept for 221 ns
Some questions I have:
- What could explain these numbers?
- Why does sleeping for a negative amount of time return 200+ ns, while sleeping for 0+ nanoseconds results in 50,000+ nanoseconds?
- Is negative numbers as a sleep time a documented/supported feature, or did I accidentally stumble across some strange bug I cannot rely upon?
- Is there a better C++ sleep call which would give me more consistent/predictable sleep times?
nanosleep({0,1}, NULL)
takes (if you have linux) – Farricasleep_for
sleeps for at least the specified duration. If you provide a negative value, it doesn't have to sleep at all.sleep
is a niche tool, though. You should probably be using some sort of timer mechanism (sad standard C++ doesn't have any) – Symbolsleep_for
is measuring the overhead of thesleep_for
call: you can't expect it to take zero time, because it has to check if it should take zero time, which takes more than zero time! Remember, however, that if you sleep for negative time, it is conforming to sleep for 7 years and 7 months. It is always conforming to sleep for longer than requested. If you need ridiculously small sleep times, you need to busy-loop, because cpu-saving sleep times end up waiting for an interrupt while other code runes... – Antilog