准确的睡眠/等待。 Windows操作系统。 1毫秒准确性

问题描述 投票:-1回答:2

我有一个程序,其中的等待/延迟必须准确。我遇到的问题是不同计算机上的等待/延迟更改(我了解cpu频率差异可能会导致此问题),我想知道是否有人可以将我指向正确的方向,以便我可以找到准确的跨计算机睡眠/等待时间。我也知道在Windows操作系统上不可能达到1ms的精度,因为它不是实时的,CPU使用率也是一个问题,因此我宁可不要热睡眠。 (c ++ lang)

static void SleepShort(float milliseconds) {
    static bool once = true;
    if (once) {
        ULONG actualResolution;
        ZwSetTimerResolution(1, true, &actualResolution);
        once = false;
    }

    LARGE_INTEGER interval;
    interval.QuadPart = -1 * (int)((milliseconds - 0.516) * 10000.0f);
    NtDelayExecution(false, &interval);
}

我在一个类似的问题上发现了这个

interval.QuadPart = -1 * (int)((milliseconds - 0.516) * 10000.0f);

-0.516似乎至少可以准确地反映我在计算机上所做的事情。此等待/睡眠用于1ms睡眠。

c++ windows wait sleep
2个回答
0
投票
#include <chrono>

全球空间:

class bla{
    double time;
    std::chrono::steady_clock::time_point start_clock;
    void upd_clock(){
        std::chrono::steady_clock::time_point current_time = std::chrono::steady_clock::now();
        time = ((double) std::chrono::duration_cast<std::chrono::miliseconds>(current_time - start_clock).count())/1000;
    }
}

在主要:

bla->start_clock = std::chrono::steady_clock::now();

在主循环中:

while(1){
    bla->upd_clock();
}

bla-> time存储时间。试用毫秒/微秒等。这是您测量时间的方式。如果它进入睡眠状态-不要让线程进入睡眠状态-醒来将比您的目标花费更长的时间。您可以仅使用更新时钟和检查时间功能来保持主线程运行。还有一件事:在类似的时间测量间隔内,您可以使用int64而不是double来编写它。


0
投票

如果可能,我建议使用<chrono>,因为它会在编译时为您捕获很多错误,并使逻辑更容易。

接下来,我建议结合使用操作系统进行睡眠和“热睡眠”。简而言之,请使用操作系统进入睡眠状态,直到达到所需的唤醒时间之前的短时间间隔,然后再旋转最后一个小的时间间隔。我在最后一次旋转间隔ymmv中使用了1ms。

#include <chrono>
#include <iostream>
#include <thread>

void
SleepShort(std::chrono::duration<float, std::milli> d)
{
    using namespace std::chrono;
    auto t = steady_clock::now() + ceil<steady_clock::duration>(d);
    if (d > 1ms)
        std::this_thread::sleep_until(t-1ms);
    while (steady_clock::now() < t)
        ;
}

我在开发上述代码时遇到的一个难题是避免float中缺乏必要的精度。我最初有以下代码:

auto t = steady_clock::now() + d;

隐式创建一个time_point,其中repfloat,周期为nanoseconds,用于测量自计算机启动以来(在我的平台上)的持续时间。事实证明float不具有表示该数量所必需的精度。随后,我的旋转循环无法正常工作。

如图所示切换为ceil,会将浮点毫秒转换为steady_clock使用的基于整数的滴答(在所有3个主要实现中为nanoseconds),现在该算法具有足够的精度以正确操作。 Fwiw,double也可以正常工作。

可以这样称呼:

SleepShort(2.5ms);
© www.soinside.com 2019 - 2024. All rights reserved.