我使用boost :: asio :: deadline_timer实现了一个计时器。 我使用expires_from_now运行一个计时器(boost :: posix_time :: milliseconds(1))
我算一下,它在10秒内(在Windows下)触发的频率。我期待10 000次。
结果如下: 在一台PC计数器上非常准确 - 每10秒10 000次。 在其他PC计数器上随机变化7000到8500。 问题:一段时间后,计数减少到每10秒600-800次。
当我仍然使用1ms间隔的定时器时,我无法找出将超时增加到~10-15ms的原因是什么。
我检查了电源管理中的处理器电源设置 - 最低性能为100%。 Windows中是否存在可能影响不同PC上的结果的其他设置? 为什么在运行程序一段时间后会发生这种情况?
答案 0 :(得分:0)
而不是等待" x"毫秒,如果您依靠最佳精确度来满足最后期限,请完全说明:
<强> Live On Coliru 强>
#include <boost/asio.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <iostream>
namespace ba = boost::asio;
using namespace std::chrono_literals;
int main() {
ba::io_context io;
using C = ba::high_resolution_timer::clock_type;
ba::high_resolution_timer t(io);
auto next_wakeup = [&t, interval = 10ms] {
t.expires_at(C::now() + interval);
t.wait();
};
auto until = C::now() + 5s;
int count = 0;
do count += 1;
while (next_wakeup(), C::now() <= until);
std::cout << "Timer triggered " << count << " times in 5s\n";
}
在我的系统上,它报告497,因此您可以看到循环开销足以错过总共几个截止日期。如果你降低频率,这就变得更加重要。
你当然可以使这个东西多线程并在线程之间分配你的计时器事件,这样就会有更少的错过。或者您可以查看experimental scheduler in Boost Thread
之类的内容如果您更改设计权衡以最大限度地减少错过的事件,则代价(可能)有更频繁的频率/间隔:
请注意每次从起点开始计算下一个事件的注意事项,以便
INTERVAL
可以精确指定time_point
在时钟{{1}中无法表示}}:auto constexpr INTERVAL = 1.0/3ms;
表示。否则可能会累积舍入误差。
<强> Live On Coliru 强>
#include <boost/asio.hpp>
#include <boost/asio/high_resolution_timer.hpp>
#include <boost/thread.hpp>
using namespace std::chrono_literals;
namespace /*static*/ {
auto constexpr INTERVAL = 1ms;
auto constexpr DURATION = 5s;
std::atomic_int count {0};
void on_timer_event() { ++count; }
}
namespace ba = boost::asio;
using Timer = ba::high_resolution_timer;
using C = Timer::clock_type;
template <typename Interval>
static void timer_chain(Timer& t, C::time_point start_point, Interval ival, int n = 0) {
t.expires_at(start_point + std::chrono::duration_cast<C::duration>(n * ival));
t.async_wait([=,&t](auto ec) {
if (!ec) {
on_timer_event();
timer_chain(t, start_point, ival, n+1);
}
});
}
#include <iostream>
int main() {
ba::io_context io;
boost::thread_group tg;
std::list<Timer> timers;
auto const slices = 10;
auto const start_point = C::now();
auto group_interval = INTERVAL * slices;
for (auto slice = 0; slice<slices; ++slice)
timer_chain(timers.emplace_back(io), start_point + slice*INTERVAL, group_interval);
for (unsigned i = 0; i < std::thread::hardware_concurrency(); ++i)
tg.create_thread([&io] { io.run_for(DURATION); });
std::cout << "Running on " << tg.size() << " threads...\n";
tg.join_all();
std::cout << "Event triggered " << count << " times in " << (C::now() - start_point)/1ms << "ms\n";
}
打印
Running on 1 threads...
Event triggered 5002 times in 5001ms
或者,在我的系统上:
Running on 8 threads...
Event triggered 5002 times in 5001ms