Delayed response for sleep function
Hi Team, When I use boost sleep function, I am getting delayed response. How to overcome this issue. Is there any alternative for this? boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::local_time(); boost::this_thread::sleep(boost::posix_time::millisec(10000)); boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::local_time(); boost::this_thread::sleep(boost::posix_time::millisec(10000)); boost::posix_time::ptime t3 = boost::posix_time::microsec_clock::local_time(); boost::posix_time::time_duration diff = t2 - t1; std::cout << diff.total_milliseconds() << std::endl; boost::posix_time::time_duration diff1 = t3 - t2; std::cout << diff1.total_milliseconds() << std::endl; output is : 10005 10006 Expected ouput should be 10000 and 10000 Regards, Rajesh D Please be advised that this email may contain confidential information. If you are not the intended recipient, please notify us by email by replying to the sender and delete this message. The sender disclaims that the content of this email constitutes an offer to enter into, or the acceptance of, any agreement; provided that the foregoing does not invalidate the binding effect of any digital or other electronic reproduction of a manual signature that is included in any attachment.
On 20/06/2022 19:10, Daggumati, Rajesh wrote:
When I use boost sleep function, I am getting delayed response. [...] output is : 10005 10006
Expected ouput should be 10000 and 10000
Sleep time is always a minimum bound, not exact, and is subject to the whims of the OS's thread scheduler. You just have to live with that. Getting less than 10ms "drift" is actually an excellent result; on a loaded system it may be a lot worse than that. There are some techniques that you can use to try to smooth out sleeps a bit (such as keeping track of the difference between requested and actual delay and adjusting your subsequent request accordingly), but these are rarely necessary (and are impossible to get "perfect" since they're only reactive; and can themselves be the source of bugs, especially in the presence of suspended power states), so they're not recommended for general use. The best method of compensating for this sort of thing depends on exactly what you're actually trying to do; different goals call for different solutions.
I was under the impression that drift compensation is often hardware supported and extremely accurate (at least for the RTCs I’ve worked on). WL
On Jun 20, 2022, at 8:49 PM, Gavin Lambert via Boost <boost@lists.boost.org> wrote:
On 20/06/2022 19:10, Daggumati, Rajesh wrote:
When I use boost sleep function, I am getting delayed response. [...] output is : 10005 10006 Expected ouput should be 10000 and 10000
Sleep time is always a minimum bound, not exact, and is subject to the whims of the OS's thread scheduler. You just have to live with that. Getting less than 10ms "drift" is actually an excellent result; on a loaded system it may be a lot worse than that.
There are some techniques that you can use to try to smooth out sleeps a bit (such as keeping track of the difference between requested and actual delay and adjusting your subsequent request accordingly), but these are rarely necessary (and are impossible to get "perfect" since they're only reactive; and can themselves be the source of bugs, especially in the presence of suspended power states), so they're not recommended for general use.
The best method of compensating for this sort of thing depends on exactly what you're actually trying to do; different goals call for different solutions.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Tue, 21 Jun 2022 at 04:08, William Linkmeyer via Boost < boost@lists.boost.org> wrote:
I was under the impression that drift compensation is often hardware supported and extremely accurate (at least for the RTCs I’ve worked on).
Most clock implementations are drift compensated either with NTP or PTP on most desktop platforms. You have a systematic delay in responding to the clock reaching the target time. Thus it is systematically late by an unknown amount in the case of a typical OS. This is normally sufficient. One can dynamically adjust the sleep interval to continuously converge to the target, at the expense of sometimes having too early responses. This dynamic adjustment can be a simple correction based on the latest sample or smoothed with an Exponential Moving Average. Alternatively you set the sleep to be less than your target by an amount and finish by spinning. This will lower jitter at the expense of more CPU usage. To optimize latency, the spinning solutions need to avoid excessive cache contention. Getting this completely optimal calls for different solutions dependent on the varying data structures being queried. The clock is probably fairly reasonable to spin on. Most platforms have the implementation extremely efficient. To take it one step further on many processors you can finish the spin with the timestamp counter; if your processors are invariant_tsc. It is necessary to get the calibration for this on many machines, but not all. TSC can drift versus system clock partly because of the resynchronization that happens with PTP/NTP. I have often used a type like a HiResClock which uses system_clock but also uses TSC with periodic correction to the coefficient required to map the clocks to time. This is a solution for a non-steady clock. For other cases where you are measuring intervals it is vital to avoid the resynchronization effects as it may resynchronize part of the way through your interval being measured. This is why we also have a steady_clock in the standard. To combine the real-time clock with the steady_clock is often disappointing since it brings back the non-steady problems through the resynchronization procedure.
WL
I hope this is helpful.
Neil Groves
#include <chrono> #include <concepts> #include <iostream> #include <iomanip> #include <ratio> #include <unistd.h> int main() { using clock_type = std::chrono::high_resolution_clock; using namespace std::literals; auto t = clock_type::now(); auto const t0 = t; auto const t1 = t0 + 1s; while(t < t1) { ::usleep(1); t = clock_type::now(); } std::cout << std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t - t0).count() << "ms\n"; } Example output: Program returned: 0 1000.47ms https://godbolt.org/z/bcGPcebP1 On Tue, 21 Jun 2022 at 10:12, Neil Groves via Boost <boost@lists.boost.org> wrote:
On Tue, 21 Jun 2022 at 04:08, William Linkmeyer via Boost < boost@lists.boost.org> wrote:
I was under the impression that drift compensation is often hardware supported and extremely accurate (at least for the RTCs I’ve worked on).
Most clock implementations are drift compensated either with NTP or PTP on most desktop platforms. You have a systematic delay in responding to the clock reaching the target time. Thus it is systematically late by an unknown amount in the case of a typical OS. This is normally sufficient. One can dynamically adjust the sleep interval to continuously converge to the target, at the expense of sometimes having too early responses. This dynamic adjustment can be a simple correction based on the latest sample or smoothed with an Exponential Moving Average. Alternatively you set the sleep to be less than your target by an amount and finish by spinning. This will lower jitter at the expense of more CPU usage.
To optimize latency, the spinning solutions need to avoid excessive cache contention. Getting this completely optimal calls for different solutions dependent on the varying data structures being queried. The clock is probably fairly reasonable to spin on. Most platforms have the implementation extremely efficient. To take it one step further on many processors you can finish the spin with the timestamp counter; if your processors are invariant_tsc. It is necessary to get the calibration for this on many machines, but not all. TSC can drift versus system clock partly because of the resynchronization that happens with PTP/NTP. I have often used a type like a HiResClock which uses system_clock but also uses TSC with periodic correction to the coefficient required to map the clocks to time. This is a solution for a non-steady clock. For other cases where you are measuring intervals it is vital to avoid the resynchronization effects as it may resynchronize part of the way through your interval being measured. This is why we also have a steady_clock in the standard. To combine the real-time clock with the steady_clock is often disappointing since it brings back the non-steady problems through the resynchronization procedure.
WL
I hope this is helpful.
Neil Groves
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 6/21/22 12:35, Richard Hodges via Boost wrote:
#include <chrono> #include <concepts> #include <iostream> #include <iomanip> #include <ratio> #include <unistd.h>
int main() { using clock_type = std::chrono::high_resolution_clock; using namespace std::literals;
auto t = clock_type::now(); auto const t0 = t; auto const t1 = t0 + 1s; while(t < t1) { ::usleep(1); t = clock_type::now(); }
std::cout << std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(t - t0).count() << "ms\n"; }
Example output:
Program returned: 0 1000.47ms
Timer precision may depend on the sleep duration. Change to sleep for 10 seconds and you get drift in the order of milliseconds: 10006.5ms https://godbolt.org/z/Gjxccz5bK
On 21/06/2022 21:35, Richard Hodges wrote:
while(t < t1) { ::usleep(1); t = clock_type::now(); }
While yes, you can do this sort of thing, my point was that most of the time if you think you need to, you're wrong. It's ok to use this sort of code for embedded hardware where you're absolutely in control of whatever else is running on the whole PC (but even then, only if you really need it, which should be seldom). Don't even think about it for a general release.
On 21/06/2022 15:08, William Linkmeyer wrote:
I was under the impression that drift compensation is often hardware supported and extremely accurate (at least for the RTCs I’ve worked on).
I was not talking about drift in the clock itself, but rather from overshooting the deadline due to the OS's thread scheduler.
There will always be a delay between measurement and observation, 5-6 ms does feel a bit high for the functions you’re calling. I’d time the execution of the functions you’re calling, averaged over many runs, to see if there is a bottleneck somewhere. I’d also check to make sure that your optimization level is 2 or 3. WL
On Jun 20, 2022, at 4:00 AM, Daggumati, Rajesh via Boost <boost@lists.boost.org> wrote:
Hi Team, When I use boost sleep function, I am getting delayed response. How to overcome this issue. Is there any alternative for this?
boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::local_time(); boost::this_thread::sleep(boost::posix_time::millisec(10000)); boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::local_time(); boost::this_thread::sleep(boost::posix_time::millisec(10000)); boost::posix_time::ptime t3 = boost::posix_time::microsec_clock::local_time(); boost::posix_time::time_duration diff = t2 - t1; std::cout << diff.total_milliseconds() << std::endl; boost::posix_time::time_duration diff1 = t3 - t2; std::cout << diff1.total_milliseconds() << std::endl;
output is : 10005 10006
Expected ouput should be 10000 and 10000
Regards, Rajesh D Please be advised that this email may contain confidential information. If you are not the intended recipient, please notify us by email by replying to the sender and delete this message. The sender disclaims that the content of this email constitutes an offer to enter into, or the acceptance of, any agreement; provided that the foregoing does not invalidate the binding effect of any digital or other electronic reproduction of a manual signature that is included in any attachment.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (6)
-
Andrey Semashev
-
Daggumati, Rajesh
-
Gavin Lambert
-
Neil Groves
-
Richard Hodges
-
William Linkmeyer