gpt4 book ai didi

c++ - performancecounter C++ 的窗口时序漂移

转载 作者:搜寻专家 更新时间:2023-10-31 01:36:27 25 4
gpt4 key购买 nike

我在我的应用程序中使用 QueryPerformanceCounter() 函数来测量时间。此功能还用于提供我的应用程序生命周期的时间线。最近我注意到其他时间函数的时间有偏差。最后,我写了一个小测试来检查漂移是否真实。 (我用的是VS2013编译器)

    #include <Windows.h>
#include <chrono>
#include <thread>
#include <cstdio>

static LARGE_INTEGER s_freq;

using namespace std::chrono;

inline double now_WinPerfCounter()
{
LARGE_INTEGER tt;
if (TRUE != ::QueryPerformanceCounter(&tt))
{
printf("Error in QueryPerformanceCounter() - Err=%d\n", GetLastError());
return -1.;
}
return (double)tt.QuadPart / s_freq.QuadPart;
}

inline double now_WinTick64()
{
return (double)GetTickCount64() / 1000.;
}

inline double now_WinFileTime()
{
FILETIME ft;
::GetSystemTimeAsFileTime(&ft);

long long * pVal = reinterpret_cast<long long *>(&ft);

return (double)(*pVal) / 10000000. - 11644473600LL;
}


int _tmain(int argc, _TCHAR* argv[])
{
if (TRUE != ::QueryPerformanceFrequency(&s_freq))
{
printf("Error in QueryPerformanceFrequency() - Err=#d\n", GetLastError());
return -1;
}

// save all timetags at the beginning
double t1_0 = now_WinPerfCounter();
double t2_0 = now_WinTick64();
double t3_0 = now_WinFileTime();
steady_clock::time_point t4_0 = steady_clock::now();

for (int i = 0;; ++i) // forever
{
double t1 = now_WinPerfCounter();
double t2 = now_WinTick64();
double t3 = now_WinFileTime();
steady_clock::time_point t4 = steady_clock::now();

printf("%03d\t %.3lf %.3lf %.3lf %.3lf \n",
i,
t1 - t1_0,
t2 - t2_0,
t3 - t3_0,
duration_cast<nanoseconds>(t4 - t4_0).count() * 1.e-9
);

std::this_thread::sleep_for(std::chrono::seconds(10));
}
return 0;
}

输出是,令人困惑:

    000      0.000 0.000 0.000 0.000
...
001 10.001 10.000 10.002 10.002
...
015 150.006 150.010 150.010 150.010
...
024 240.009 240.007 240.015 240.015
...
025 250.010 250.007 250.015 250.015
...
026 260.010 260.007 260.016 260.016
...
070 700.027 700.039 700.041 700.041

为什么会有差异?使用不同的 API 函数时,一秒的持续时间看起来不一样?此外,在一天中,差异不是恒定的...

最佳答案

这是正常的,负担得起的时钟永远不会具有无限的精度。 GetSystemTime() 和 GetTickCount() 会定期从 Internet 时间服务器(默认为 time.windows.com)重新校准。它使用负担不起的原子钟来计时。追赶或减速的调整是渐进的,以避免让软件心脏病发作。他们报告的时间最多会偏离地球自转几秒钟,定期重新校准会限制长期漂移误差。

但是 QPF 没有经过校准,它的分辨率太高,无法让这些调整不影响它通常用于的短间隔测量。它源自芯片组上可用的频率源,由系统构建者选择。受制于典型的电子零件公差,温度尤其会影响精度并导致较长时间的可变漂移。因此QPF只适用于测量相对较短的间隔。

不可避免地,两个时钟不可能相同,您看到它们漂移开来。您必须选择一个或另一个作为“主”时钟。如果长期精度很重要,那么您必须选择校准源,如果高分辨率而不是精度很重要,则选择 QPF。如果两者都很重要,那么您需要定制硬件,例如 GPS 时钟。

关于c++ - performancecounter C++ 的窗口时序漂移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35601880/

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