首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高精度睡眠值在5ms左右

高精度睡眠值在5ms左右
EN

Stack Overflow用户
提问于 2022-10-05 16:16:56
回答 1查看 104关注 0票数 1

我正在寻找解决方案,这将给我最准确的睡眠一个函数的小值。我尝试了下面的代码来测试它:

代码语言:javascript
复制
#include <thread>
#include <chrono>
#include <functional>
#include <windows.h>

using ms = std::chrono::milliseconds;
using us = std::chrono::microseconds;
using ns = std::chrono::nanoseconds;
const int total_test = 100;
const int sleep_time = 1;
template <typename F,typename T>
long long sleep_soluion_tester(T desired_sleep_time, F func)
{
    long long avg = 0.0;
    for (int i = 0; i < total_test; i++)
    {
        auto before = std::chrono::steady_clock::now();
        func(desired_sleep_time);
        auto after = std::chrono::steady_clock::now();
        avg += std::chrono::duration_cast<T>(after - before).count();
    }
    return avg / total_test;
};
template <typename F>
ms sleep_soluion_tester(int desired_sleep_time, F func)
{
    ms avg = ms(0);
    for (int i = 0; i < total_test; i++)
    {
        auto before = std::chrono::steady_clock::now();
        func(desired_sleep_time);
        auto after = std::chrono::steady_clock::now();
        avg += std::chrono::duration_cast<ms>(after - before);
    }
    return avg / total_test;
};
int main()
{
    auto sleep = [](auto time) {
        std::this_thread::sleep_for(time);
    };
    ms sleep_test1 = static_cast<ms>(sleep_time);
    us sleep_test2 = static_cast<us>(sleep_test1);
    ns sleep_test3 = static_cast<ns>(sleep_test1);
    std::cout << " desired sleep time: " << sleep_time << "ms\n";
    std::cout << " using Sleep(desired sleep time) "<< sleep_soluion_tester(sleep_time, Sleep).count() << "ms\n";
    std::cout << " using this_thread::sleep_for(ms) " << sleep_soluion_tester(sleep_test1,sleep) << "ms\n";
    std::cout << " using this_thread::sleep_for(us) " << sleep_soluion_tester(sleep_test2,sleep) << "ms\n";
    std::cout << " using this_thread::sleep_for(ns) " << sleep_soluion_tester(sleep_test3,sleep) << "ms\n\n";

但是似乎没有什么区别,即使传递的参数是1ms,它们都需要大约15毫秒才能完成。是否有一种方法可以提高休眠函数的精度(或者某些实现会导致更高的精度)?

我知道使用线程睡眠是一种不确定的方法,因为调度程序将决定什么时候线程将被恢复,但是我想知道是否有任何提高精度的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-05 17:03:37

好吧,在标准的桌面操作系统上,睡眠时间很短是不能保证的。

此外,您还必须处理两个方面:

  1. 时间测量:如果测量方法的时间分辨率很低,那么在测量时可能会得到完全错误的结果。
  2. 睡眠功能本身的时间分辨率。

然后,在非实时操作系统(如Windows、MacOS和Linux )上也可能发生这样的情况,即您的进程/线程无法及时安排,以便足够早地唤醒。如果睡眠时间较短,则更有可能发生这种情况。

因此,在Windows上,您可以使用WIN32 API并调整计时器周期,并将其设置为最低可能的值:

代码语言:javascript
复制
timeBeginPeriod(1); // set period to 1 ms

在任务或程序的末尾--根据文档--您必须以

代码语言:javascript
复制
timeEndPeriod(1);

然后可以使用WIN32睡眠功能:

代码语言:javascript
复制
Sleep(1); // (try to) sleep 1 ms

根据文件:

如果dwMilliseconds小于系统时钟的分辨率,则线程可能睡眠时间小于指定的时间长度。如果dwMilliseconds大于一个滴答,但小于两个,则等待时间可以在一到两个滴答之间,依此类推。有关更多信息,请参见此处:https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep

在Linux上,您可以尝试使用纳米睡眠,请参阅https://man7.org/linux/man-pages/man2/nanosleep.2.html

对于时间测量,您可以分别在QueryPerformanceCounter上和clock_gettime上使用Linux上的clock_gettime函数。

这些都不能保证你每次睡觉时都能达到1毫秒的分辨率。但是timeBeginPeriod是一种尝试,因为根据文档,默认的定时器分辨率是15,6ms,这完全符合您的测量标准。设置一个更高的分辨率,例如,1毫秒可能会帮助你。对于需要“真实”实时保证功能的任务来说,这是不够的。为此,构建了实时OSes。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73963381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档