【问题标题】:c++ while loop timer varying wildly in accuracyc ++ while循环计时器的准确性变化很大
【发布时间】:2019-04-23 19:24:39
【问题描述】:

我正在尝试使用 while 循环来创建一个持续测量 3000μs (3 ms) 的计时器,虽然它大部分时间都在工作,但其他时候计时器可能会延迟多达 500μs。为什么会发生这种情况,有没有更精确的方法来制作这样的计时器?

int getTime() {
    chrono::microseconds μs = chrono::duration_cast< chrono::microseconds >(
        chrono::system_clock::now().time_since_epoch() //Get time since last epoch in μs
        );
    return μs.count(); //Return as integer
}

int main()
{
    int target = 3000, difference = 0;
    while (true) {
        int start = getTime(), time = start;
        while ((time-start) < target) {
            time = getTime();
        }
        difference = time - start;
        if (difference - target > 1) { //If the timer wasn't accurate to within 1μs
            cout << "Timer missed the mark by " + to_string(difference - target) + " microseconds" << endl; //Log the delay
        }
    }
    return 0;
}

我希望这段代码记录的延迟始终在 5 微秒左右,但 the console output looks like this

编辑澄清:我在 Windows 10 Enterprise Build 16299 上运行,但该行为在 Debian 虚拟机上仍然存在。

【问题讨论】:

标签: c++


【解决方案1】:

您还需要考虑其他正在运行的进程。操作系统可能会抢占您的进程以将 CPU 时间分配给其他进程/线程,并且会不确定地将控制权返回给运行此计时器的进程/线程。

当然,当我们考虑实时操作系统或平面调度程序时,这并不是 100% 正确的。但如果您在通用机器上运行,您的代码中可能会出现这种情况。

【讨论】:

  • 所以这是在 Windows 上运行我的代码的问题,而不是我的代码的问题?
  • 几乎,实时操作系统意味着您可以拥有确定性的性能,而 Windows 绝对不是其中之一。没有操作系统的微处理器是我知道的唯一可以在几个时钟周期内保证准确性的地方。机器人的 ROS 和其他一些 linux 变体可能会让您不到一微秒,但不确定它们的准确度下限是什么,超过没有操作系统。
  • 请注意,ROS 本身并不是一个操作系统,而是一个元操作系统。它的调度器也与 OS 调度器并行运行。
【解决方案2】:

由于您在 Windows 上运行,RTOS 负责通过 NTP 保持时间,因为 C++ 没有内置函数。查看SetTimer() 函数的此 Windows API:http://msdn.microsoft.com/en-us/library/ms644906(v=vs.85).aspx

如果您想通过 C++ 获得最佳和最高分辨率的时钟,请查看 chrono 库:

#include <iostream>
#include <chrono>
#include "chrono_io"

int main()
{
    typedef std::chrono::high_resolution_clock Clock;
    auto t1 = Clock::now();
    auto t2 = Clock::now();
    std::cout << t2-t1 << '\n';
}

【讨论】:

  • 使用 Lubuntu 18.04、g++ 7.3.0 在我的旧戴尔上进行的测量:每次“时间(nullptr)”事件需要 3.95 秒;每个 'Posix clock_gettime (CLOCK_REALTIME, &ts);' 1.288 µ 秒事件;每个“HRClk_t:now()”事件需要 1.382 µ 秒。 chrono high-resolution-clock 并不比 'Posix clock' 慢太多。
  • 如果您使用的是 Ubuntu,请记住,由于内核进程不同,时间的计算速度与 Windows 不同。 Posix 仅适用于 Linux,与 chrono 不同,在 Windows 上不受支持。您还会遇到 Posix 的 2038 年问题。
猜你喜欢
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多