久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

Windows 7 計時功能 - 如何正確使用 GetSystemTimeAdju

Windows 7 timing functions - How to use GetSystemTimeAdjustment correctly?(Windows 7 計時功能 - 如何正確使用 GetSystemTimeAdjustment?)
本文介紹了Windows 7 計時功能 - 如何正確使用 GetSystemTimeAdjustment?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我在 Windows 7 上使用 GetSystemTimeAdjustment 函數運行了一些測試,得到了一些我無法解釋的有趣結果.據我所知,如果系統時間是定期同步的,則此方法應該返回,如果是,則以哪個間隔和以哪個增量更新(參見 MSDN 上的 GetSystemTimeAdjustment 函數).

從這里我遵循,如果我查詢系統時間,例如使用 GetSystemTimeAsFileTime 重復我應該要么沒有變化(系統時鐘尚未更新),要么是變化的倍數GetSystemTimeAdjustment 檢索到的增量.問題一:這個假設正確嗎?

現在考慮以下測試代碼:

#include #include #include int main(){FILETIME 文件開始;GetSystemTimeAsFileTime(&fileStart);ULARGE_INTEGER 開始;start.HighPart = fileStart.dwHighDateTime;start.LowPart = fileStart.dwLowDateTime;for (int i=20; i>0; --i){FILETIME時間戳1;ULARGE_INTEGER ts1;GetSystemTimeAsFileTime(&timeStamp1);ts1.HighPart = timeStamp1.dwHighDateTime;ts1.LowPart = timeStamp1.dwLowDateTime;std::cout <<時間戳:" <<std::setprecision(20) <<(double)(ts1.QuadPart - start.QuadPart)/10000000 <<std::endl;}DWORD dwTimeAdjustment = 0, dwTimeIncrement = 0, dwClockTick;BOOL fAdjustmentDisabled = TRUE;GetSystemTimeAdjustment(&dwTimeAdjustment, &dwTimeIncrement, &fAdjustmentDisabled);std::cout <<"
時間調整禁用:" <<f 調整禁用<<"
時間調整:" <<(double)dwTimeAdjustment/10000000<<"
時間增量:" <<(double)dwTimeIncrement/10000000 <<std::endl;}

它在一個循環中需要 20 個時間戳并將它們打印到控制臺.最后,它打印系統時鐘更新的增量.我希望循環中打印的時間戳之間的差異是此增量的 0 或倍數.但是,我得到這樣的結果:

時間戳:0時間戳:0.0025000000000000001時間戳:0.0074999999999999997時間戳:0.01時間戳:0.012500000000000001時間戳:0.014999999999999999時間戳:0.017500000000000002時間戳:0.022499999999999999時間戳:0.025000000000000001時間戳:0.0275時間戳:0.029999999999999999時間戳:0.032500000000000001時間戳:0.035000000000000003時間戳:0.040000000000000001時間戳:0.042500000000000003時間戳:0.044999999999999998時間戳:0.050000000000000003時間戳:0.052499999999999998時間戳:0.055時間戳:0.057500000000000002時間調整禁用:0時間調整:0.0156001時間增量:0.0156001

因此看起來系統時間是使用大約 0.0025 秒而不是 GetSystemTimeAdjustment 返回的 0.0156 秒的間隔更新的.

問題二:這是什么原因?

解決方案

GetSystemTimeAsFileTimeAPI 提供對文件時間格式的系統掛鐘的訪問.

64 位 FILETIME 結構以 100ns 為單位接收系統時間作為 FILETIME,該時間自 1601 年 1 月 1 日起已過期.對 GetSystemTimeAsFileTime 的調用通常需要 10 ns 到 15 ns.

為了調查此 API 提供的系統時間的真實準確性,需要討論與時間值一起出現的粒度.換句話說:系統時間多久更新一次?第一個估計值由隱藏的 API 調用提供:

NTSTATUS NtQueryTimerResolution(OUT PULONG MinimumResolution,OUT PULONG 最大分辨率,OUT PULONG 實際分辨率);

NtQueryTimerResolution 由本地 Windows NT 庫 NTDLL.DLL 導出.本次調用上報的ActualResolution以100ns為單位表示系統時間的更新周期,不一定與中斷周期匹配.該值取決于硬件平臺.常見硬件平臺為 ActualResolution 報告 156,250 或 100,144;較舊的平臺可能會報告更大的數字;較新的系統,尤其是在支持 HPET(高精度事件計時器)或 常量/不變 TSC 時,可能會為 ActualResolution 返回 156,001.

這是控制系統的心跳之一.MinimumResolutionActualResolution 與多媒體計時器配置相關.

ActualResolution 可以通過 API 調用設置

NTSTATUS NtSetTimerResolution(IN ULONG RequestedResolution,在布爾集合中,OUT PULONG 實際分辨率);

或通過多媒體定時器界面

MMRESULT timeBeginPeriod(UINT uPeriod);

從允許的范圍推導出 uPeriod 的值

MMRESULT timeGetDevCaps(LPTIMECAPS ptc, UINT cbtc);

填充結構

typedef struct {UINT wPeriodMin;UINT wPeriodMax;TIMECAPS;

wPeriodMin 的典型值為 1 ms,wPeriodMax 的典型值為 1,000,000 ms.

在這里查看最小值/最大值時存在一個不幸的誤解:

  • wPeriodMin 定義了最短時間段,在此上下文中很清楚.
  • MinimumResolution 另一方面由 NtQueryTimerResolution 返回指定分辨率.可獲得的最低分辨率(MinimumResolution)可達20 ms左右,而可獲得的最高分辨率(MaximumResolution)可達0.5 ms.但是,無法通過 timeBeginPeriod 訪問 0.5 毫秒的結果.

多媒體定時器接口處理周期,NtQueryTimerResolution() 處理分辨率(周期的倒數).

總結: GetSystemTimeAdjustment 不是要查看的函數.此功能僅說明如何以及是否完成時間更改.根據多媒體定時器界面timeBeginPeriod的設置,時間進度可能會更頻繁,更小部分.使用 NtQueryTimerResolution 接收實際時間增量.請注意,多媒體計時器 API 的設置確實會影響這些值.(例如:當媒體播放器播放視頻時,時間越來越短.)

我診斷出 Windows 時間在很大程度上很重要.部分結果可以在此處找到.

注意:時間調整:0.0156001在您的系統上使用 HPET 和/或 constant/invariant TSC 清楚地識別 Windows VISTA 或更高版本.

實施:如果你想抓住時間的轉變:

FILETIME FileTime,LastFileTime;長長的到期時間,最后時間;長 FileTimeTransitionPeriod;GetSystemTimeAsFileTime(&FileTime);for (int i = 0; i <20; i++) {LastFileTime.dwLowDateTime = FileTime.dwLowDateTime;while (FileTime.dwLowDateTime == LastFileTime.dwLowDateTime) GetSystemTimeAsFileTime(&FileTime);//足以只看低部分來捕捉過渡CopyMemory(&DueTime,&FileTime,sizeof(FILETIME));CopyMemory(&LastTime,&LastFileTime,sizeof(FILETIME));FileTimeTransitionPeriod = (long)(DueTime-LastTime);fprintf(stdout,"transition period: % 7.4lf ms)
",(double)(FileTimeTransitionPeriod)/10000);}//警告:此代碼以 20 個文件時間增量消耗 100% 的 cpu.//在 15.625 毫秒的標準文件時間增量下,這對應于 312.5 毫秒!

但是:當文件時間轉換非常短時(例如由 timeBeginPeriod(wPeriodMin) 設置)任何輸出,如 fprintfstd::cout 可能會破壞結果,因為它會延遲循環.在這種情況下,我建議將 20 個結果存儲在一個數據結構中,然后再進行輸出.

并且:文件時間轉換可能并不總是相同的.很可能是文件時間增量與更新周期不匹配.請參閱上面的鏈接以獲取有關此行為的更多詳細信息和示例.

調用 timeBeginPeriod 時要小心,因為頻繁調用會顯著影響系統時鐘 MSDN.此行為適用于 Windows 版本 7.

timeBeginPeriod/timeEndPeriodNtSetTimerResolution 的調用可能會改變系統時間與ActualResolution 一樣多.經常這樣做會導致系統時間發生相當大的變化.但是,當在系統時間轉換時或附近進行調用時,偏差要小得多.對于要求苛刻的應用程序(如 NTP 客戶端),建議在調用上述函數之前輪詢系統時間轉換/增量.當系統時間進程發生意外跳轉時,很難同步到 NTP 服務器.

I ran some tests using the GetSystemTimeAdjustment function on Windows 7, and got some interesting results which I cannot explain. As fas as I understand, this method should return if the system time is synchronized periodically and if it is, at which interval and with which increment it is updated (see GetSystemTimeAdjustment function on MSDN).

From this I follow that if I query the system time for example using GetSystemTimeAsFileTime repeatingly I should either get no change (the system clock has not been updated), or a change which is a multiple of the increment retrieved by GetSystemTimeAdjustment. Question one: Is this assumption correct?

Now consider the following testing code:

#include <windows.h>
#include <iostream>
#include <iomanip>

int main()
{
    FILETIME fileStart;
    GetSystemTimeAsFileTime(&fileStart);
    ULARGE_INTEGER start;
    start.HighPart = fileStart.dwHighDateTime;
    start.LowPart = fileStart.dwLowDateTime;

    for (int i=20; i>0; --i)
    {
        FILETIME timeStamp1;
        ULARGE_INTEGER ts1;

        GetSystemTimeAsFileTime(&timeStamp1);

        ts1.HighPart = timeStamp1.dwHighDateTime;
        ts1.LowPart  = timeStamp1.dwLowDateTime;

        std::cout << "Timestamp: " << std::setprecision(20) << (double)(ts1.QuadPart - start.QuadPart) / 10000000 << std::endl;

    }

    DWORD dwTimeAdjustment = 0, dwTimeIncrement = 0, dwClockTick;
    BOOL fAdjustmentDisabled = TRUE;
    GetSystemTimeAdjustment(&dwTimeAdjustment, &dwTimeIncrement, &fAdjustmentDisabled);

    std::cout << "
Time Adjustment disabled: " << fAdjustmentDisabled
        << "
Time Adjustment: " << (double)dwTimeAdjustment/10000000
        << "
Time Increment: " << (double)dwTimeIncrement/10000000 << std::endl;

}

It takes 20 timestamps in a loop and prints them to the console. In the end it prints the increment with which the system clock is updated. I would expect the differences between the timestamps printed in the loop to be either 0 or multiples of this increment. However, I get results like this:

Timestamp: 0
Timestamp: 0.0025000000000000001
Timestamp: 0.0074999999999999997
Timestamp: 0.01
Timestamp: 0.012500000000000001
Timestamp: 0.014999999999999999
Timestamp: 0.017500000000000002
Timestamp: 0.022499999999999999
Timestamp: 0.025000000000000001
Timestamp: 0.0275
Timestamp: 0.029999999999999999
Timestamp: 0.032500000000000001
Timestamp: 0.035000000000000003
Timestamp: 0.040000000000000001
Timestamp: 0.042500000000000003
Timestamp: 0.044999999999999998
Timestamp: 0.050000000000000003
Timestamp: 0.052499999999999998
Timestamp: 0.055
Timestamp: 0.057500000000000002

Time Adjustment disabled: 0
Time Adjustment: 0.0156001
Time Increment: 0.0156001

So it appears that the system time is updated using an interval of about 0.0025 seconds and not 0.0156 seconds as return by GetSystemTimeAdjustment.

Question two: What is the reason for this?

解決方案

The GetSystemTimeAsFileTimeAPI provides access to the system's wall clock in file time format.

A 64-bit FILETIME structure receives the system time as FILETIME in 100ns units, which have been expired since Jan 1, 1601. The call to GetSystemTimeAsFileTime typically requires 10 ns to 15 ns.

In order to investigate the real accuracy of the system time provided by this API, the granularity that comes along with the time values needs to be discussed. In other words: How often is the system time updated? A first estimate is provided by the hidden API call:

NTSTATUS NtQueryTimerResolution(OUT PULONG MinimumResolution, 
                                OUT PULONG MaximumResolution, 
                                OUT PULONG ActualResolution);

NtQueryTimerResolution is exported by the native Windows NT library NTDLL.DLL. The ActualResolution reported by this call represents the update period of the system time in 100 ns units, which does not necessarily match the interrupt period. The value depends on the hardware platform. Common hardware platforms report 156,250 or 100,144 for ActualResolution; older platforms may report even larger numbers; newer systems, particulary when HPET (High Precision Event Timer) or constant/invariant TSC are supported, may return 156,001 for ActualResolution.

This is one of the heartbeats controlling the system. The MinimumResolution and the ActualResolution are relevant for the multimedia timer configuration.

The ActualResolution can be set by using the API call

NTSTATUS NtSetTimerResolution(IN ULONG RequestedResolution,
                              IN BOOLEAN Set,
                              OUT PULONG ActualResolution);

or via the multimedia timer interface

MMRESULT timeBeginPeriod(UINT uPeriod);

with the value of uPeriod derived from the range allowed by

MMRESULT timeGetDevCaps(LPTIMECAPS ptc, UINT cbtc );

which fills the structure

typedef struct {
  UINT wPeriodMin;
  UINT wPeriodMax;
} TIMECAPS;

Typical values are 1 ms for wPeriodMin and 1,000,000 ms for wPeriodMax.

There is an unfortunate misinterpretation when looking an the min/max values here:

  • wPeriodMin defines the minimum period, which is clear in this context.
  • MinimumResolution returned by NtQueryTimerResolution on the other hand specifies a resolution. The lowest obtainable resolution (MinimumResolution) is in the range of up to about 20 ms, while the highest obtainable resolution (MaximumResolution) can be 0.5 ms. However, the 0.5 ms resulution is not accessable through a of timeBeginPeriod.

The multimedia timer interface handles periods and NtQueryTimerResolution() handles resolutions (reciprocal value of period).

Summary: GetSystemTimeAdjustment is not the function to look at. This function only tells how and if time-changes are done. Depending on the setting of the multimedia timer interface timeBeginPeriod, the progress of time may be done more often and in smaller portions. Use NtQueryTimerResolution to receive the actual time increment. And be aware that the setting of the multimedia timer API does influence the values. (Example: When the media player is showing a video, the times are getting short.)

I diagnosed windows time matters to a large extent. Some of the results can be found here.

Note: Time Adjustment: 0.0156001 clearly identifies windows VISTA or higher with HPET and/or constant/invariant TSC on your system.

Implementation: If you want to catch the time transition:

FILETIME FileTime,LastFileTime;
long long DueTime,LastTime;
long FileTimeTransitionPeriod; 

GetSystemTimeAsFileTime(&FileTime);
for (int i = 0; i < 20; i++) {
  LastFileTime.dwLowDateTime = FileTime.dwLowDateTime;
  while (FileTime.dwLowDateTime == LastFileTime.dwLowDateTime) GetSystemTimeAsFileTime(&FileTime); 
  // enough to just look at the low part to catch the transition
  CopyMemory(&DueTime,&FileTime,sizeof(FILETIME));
  CopyMemory(&LastTime,&LastFileTime,sizeof(FILETIME));
  FileTimeTransitionPeriod = (long)(DueTime-LastTime);
  fprintf(stdout,"transition period: % 7.4lf ms)
",(double)(FileTimeTransitionPeriod)/10000);
}   

// WARNING: This code consumes 100% of the cpu for 20 file time increments.
// At the standard file time increment of 15.625 ms this corresponds to 312.5ms!

But: When the filetime transition is very short (e.g. set by timeBeginPeriod(wPeriodMin)) any output like fprintf or std::cout might destroy the result because it delays the loop. In such cases I'd recommend to store the 20 results in a data structure and do the output afterwards.

And: The filetime transition may not always be the same. It may well be that the file time increment does not match the update period. See the link above to get more details and examples for this bahavior.

Edit: Use caution when calling timeBeginPeriod, as frequent calls can significantly affect the system clock MSDN. This behavior applies up to Windows version 7.

Calls to timeBeginPeriod/timeEndPeriod or NtSetTimerResolution may change the system time by as much as ActualResolution. Doing it very often results in considerable changes of the system time. However, when the calls are made at or near the transition of the system time, deviations are much less. Polling for a system time transition/increment ahead of calls to the above function is advised for demanding applications like NTP clients. Synchronizing to an NTP server is difficult when unwanted jumps in the systemtime progess occurs.

這篇關于Windows 7 計時功能 - 如何正確使用 GetSystemTimeAdjustment?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

What is the fastest way to transpose a matrix in C++?(在 C++ 中轉置矩陣的最快方法是什么?)
Sorting zipped (locked) containers in C++ using boost or the STL(使用 boost 或 STL 在 C++ 中對壓縮(鎖定)容器進行排序)
Rotating a point about another point (2D)(圍繞另一個點旋轉一個點 (2D))
Image Processing: Algorithm Improvement for #39;Coca-Cola Can#39; Recognition(圖像處理:Coca-Cola Can 識別的算法改進)
How do I construct an ISO 8601 datetime in C++?(如何在 C++ 中構建 ISO 8601 日期時間?)
Sort list using STL sort function(使用 STL 排序功能對列表進行排序)
主站蜘蛛池模板: 欧美精品一区二区免费 | 羞羞的视频免费在线观看 | 欧美亚洲一区二区三区 | 91文字幕巨乱亚洲香蕉 | 国产成人精品久久二区二区91 | 久久午夜视频 | 一区二区在线观看免费视频 | 日日综合| 国产高清视频一区 | 91精品中文字幕一区二区三区 | 99综合网 | 天天干夜夜拍 | 91porn国产成人福利 | 亚洲久草 | 欧美精品片 | 成人a在线 | 亚洲欧美一区二区三区国产精品 | 日韩在线播放中文字幕 | 精品一区二区在线观看 | 亚洲欧美日韩久久久 | 粉嫩一区二区三区国产精品 | 国产在线播放一区二区三区 | 韩日精品一区 | 天天干天天爽 | 国产成人精品免高潮在线观看 | 亚洲三区视频 | 亚洲狠狠| 久久久久久成人 | 亚洲精品乱码久久久久久按摩 | 欧美国产精品一区二区三区 | 免费一级网站 | 国产成人精品久久 | 国产黄色网 | 日本网站免费观看 | 嫩草黄色影院 | 久久久久精 | 亚洲欧美视频在线观看 | 亚洲精品久久久一区二区三区 | 99精品欧美一区二区蜜桃免费 | 欧美成人一区二区三区片免费 | 日韩精品一区二区三区 |