![](/img/trans.png)
[英]Is it correct to use std::chrono::steady_clock time across the system?
[英]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.dll和msvcp140d.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.dll
与msvcp140.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.