簡體   English   中英

Visual Studio 2017 CRT實現的std :: chrono :: system_time使用哪個時鍾?

[英]What clock does the Visual Studio 2017 CRT implementation of std::chrono::system_time use?

chrono標頭中的注釋只是說

// wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime

但是它實際上使用了什么(即,我期望達到什么精度)? 該實現調用_Xtime_get_ticks ,但是該函數是不透明的。

long long _Xtime_get_ticks()
{   /* get system time in 100-nanosecond intervals since the epoch */
FILETIME ft;
__crtGetSystemTimePreciseAsFileTime(&ft);
return ((((long long)ft.dwHighDateTime) << 32)
    + (long long)ft.dwLowDateTime - EPOCH);
}

在CRT調用GetSystemTimePreciseAsFileTime時可用, GetSystemTimeAsFileTime否則。 GetSystemTimePreciseAsFileTime為您提供盡可能最高的精度(<1us)

在運行時初始化的某個時候,調用了一個名為initialize_pointers的函數,該函數基本上執行以下操作(反編譯和簡化):

HMODULE hModule = GetModuleHandleW(L"kernel32.dll");

__encodedKERNEL32Functions[0] = (void *)GetProcAddress(hModule, "FlsAlloc");
__encodedKERNEL32Functions[1] = (void *)GetProcAddress(hModule, "FlsFree");
__encodedKERNEL32Functions[2] = (void *)GetProcAddress(hModule, "FlsGetValue");
__encodedKERNEL32Functions[3] = (void *)GetProcAddress(hModule, "FlsSetValue");

...


__encodedKERNEL32Functions[24] = (void *)GetProcAddress(hModule, "GetSystemTimePreciseAsFileTime");

...

在裝有Windows 8或更高版本的__encodedKERNEL32Functions[24]將為非零。

然后歸結為:

std::chrono::system_clock::now()
-> _Xtime_get_ticks
   -> __crtGetSystemTimePreciseAsFileTime(FILETIME *)

void __crtGetSystemTimePreciseAsFileTime(FILETIME *lpSystemTimeAsFileTime)
{
    void (*f)(FILETIME *) = (void (*)(FILETIME *))__encodedKERNEL32Functions[24];
    if (f)                         // if GetSystemTimePreciseAsFileTime exists
        f(lpSystemTimeAsFileTime); // call it
    else
        GetSystemTimeAsFileTime(lpSystemTimeAsFileTime);
}

至少(大約)這是在14.16.27024.1版本的msvcp140.dllmsvcp140d.dll中實現的方式

所有這些當然都是無證的,可能會發生變化。

如果需要使用GetSystemTimePreciseAsFileTime ,則應編寫自己的時鍾,而不要依賴於實現細節。

讓我們在這里做一些研究。 首先,在Visual C ++運行時庫中找到“ _Xtime_get_ticks ”:

C:\Windows\SysWOW64>dumpbin /exports msvcp140.dll|findstr /I "Xtime"
       1483  5CA 0000B5D0 _Xtime_diff_to_millis
       1484  5CB 0000B610 _Xtime_diff_to_millis2
       1485  5CC 0000B650 _Xtime_get_ticks
       1515  5EA 0000B730 xtime_get

然后,我在同一目錄msvcp140.i386.pdb dumpbin /disasm msvcp140.dllmsvcp140.i386.pdb文件一起使用:

__Xtime_get_ticks:
  1000B650: ... boilerplate ...
  1000B659: E8 22 50 02 00     call        ___crtGetSystemTimePreciseAsFileTime

在此反匯編函數中的任何地方都沒有針對GetSystemTimeAsFileTime call指令,因此很顯然, GetSystemTimePreciseAsFileTime實際上是為底層實現調用的唯一函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM