gpt4 book ai didi

c++ - 睡了一个确切的时间

转载 作者:可可西里 更新时间:2023-11-01 18:03:42 25 4
gpt4 key购买 nike

我对 Sleep 函数的理解是它遵循“至少语义”,即 sleep(5) 将保证线程休眠 5 秒,但它可能会保持阻塞超过 5 秒,具体取决于其他因素。有没有办法在指定的时间段内休眠(无需忙等待)。

最佳答案

正如其他人所说,您确实需要使用实时操作系统来尝试实现这一目标。精确的软件计时非常棘手。

然而...虽然并不完美,通过简单地提高需要更好时机的进程的优先级,您可以获得比“正常”更好的结果。在 Windows 中,您可以使用 SetPriorityClass 实现此目的功能。如果您将优先级设置为最高级别 (REALTIME_PRIORITY_CLASS: 0x00000100),您将获得好得多的计时结果。再次重申 - 不过,这不会像您要求的那样完美。

这也可能在 Windows 以外的其他平台上实现,但我从来没有理由这样做,所以没有测试过。

编辑:根据 Andy T 的评论,如果您的应用程序是多线程的,您还需要注意分配给线程的优先级。对于 Windows,这已记录在案 here .


一些背景...

前一段时间,我使用 SetPriorityClass 来提高我正在对高速视频进行实时分析的应用程序的优先级,并且我不会错过任何一帧。帧以每秒 300 帧 (fps) 的非常常规频率(由外部帧抓取器硬件驱动)到达 PC,这会在我随后处理的每一帧上触发硬件中断。由于时间非常重要,我收集了很多关于中断时间的统计数据(使用 QueryPerformanceCounter 东西)来了解情况到底有多糟糕,并对由此产生的分布感到震惊。我没有方便的统计数据,但基本上 Windows 在以正常优先级运行时只要感觉需要就可以为中断提供服务。直方图非常困惑,stdev 比我的 ~3ms 周期更宽。在中断服务中,我经常会有 200 毫秒或更长的巨大间隙(回想一下,中断大约每 3 毫秒触发一次)!!即:硬件中断远非准确!您受制于操作系统决定为您执行的操作。

但是 - 当我发现 REALTIME_PRIORITY_CLASS 设置并使用该优先级进行基准测试时,它明显更好并且服务间隔分布非常紧凑。我可以以 300 fps 的速度运行 10 分钟而不会错过任何一帧。测得的中断服务周期几乎正好是 1/300 秒,分布很紧。

另外 - 尽量减少操作系统正在做的其他事情,以帮助提高您的计时在应用程序中更好地工作的可能性。例如:在您尝试使用其他代码获得精确计时时,没有背景视频转码或磁盘碎片整理或任何东西!!

总结:

  1. 如果您真的需要这个,请使用实时操作系统
  2. 如果您不能使用实时操作系统(不可能或不切实际),提高您的进程优先级可能会大大改善您的时间安排,就像我所做的那样
  3. HW 中断不会这样做......操作系统仍然需要决定为它们提供服务!
  4. 确保您没有运行许多其他进程来争夺操作系统的注意力
  5. 如果时机对您来说真的很重要,请进行一些测试。虽然让代码在您希望的时间准确运行不是很容易,但测量这种偏差非常容易。 PC 中的高性能计数器(通过 QueryPerformanceCounter 获得的)非常好。

因为它可能会有帮助(虽然有点偏离主题),所以这是我很久以前写的一个小类,用于在 Windows 机器上使用高性能计数器。它可能对您的测试有用:

CHiResTimer.h

#pragma once
#include "stdafx.h"
#include <windows.h>

class CHiResTimer
{
private:
LARGE_INTEGER frequency;
LARGE_INTEGER startCounts;
double ConvertCountsToSeconds(LONGLONG Counts);
public:
CHiResTimer(); // constructor
void ResetTimer(void);
double GetElapsedTime_s(void);
};

CHiResTimer.cpp

#include "stdafx.h"
#include "CHiResTimer.h"

double CHiResTimer::ConvertCountsToSeconds(LONGLONG Counts)
{
return ((double)Counts / (double)frequency.QuadPart) ;
}

CHiResTimer::CHiResTimer()
{
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&startCounts); // starts the timer right away
}

void CHiResTimer::ResetTimer()
{
QueryPerformanceCounter(&startCounts); // reset the reference counter
}

double CHiResTimer::GetElapsedTime_s()
{
LARGE_INTEGER countsNow;
QueryPerformanceCounter(&countsNow);
return ConvertCountsToSeconds(countsNow.QuadPart - startCounts.QuadPart);
}

关于c++ - 睡了一个确切的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5209408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com