Chrono头文件中的注释只是说
// wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime
但是它实际使用的是什么精度(即我可以期望什么精度)?该实现调用_Xtime_get_ticks
,但该函数是不透明的。
Chrono头文件中的注释只是说
// wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime
但是它实际使用的是什么精度(即我可以期望什么精度)?该实现调用_Xtime_get_ticks
,但该函数是不透明的。
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");
...
__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);
}
至少在 msvcp140.dll 和 msvcp140d.dll 的版本14.16.27024.1 中,它的实现方式是这样的(大约)。
所有这些当然都没有文档记录,并且可能会发生改变。
如果您需要使用 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
然后,我使用dumpbin /disasm msvcp140.dll
命令,同时在同一目录下放置msvcp140.i386.pdb
文件:
__Xtime_get_ticks:
1000B650: ... boilerplate ...
1000B659: E8 22 50 02 00 call ___crtGetSystemTimePreciseAsFileTime
在这个反汇编函数中,没有任何 GetSystemTimeAsFileTime
的 call
指令,因此很明显 GetSystemTimePreciseAsFileTime
是底层实现中唯一被调用的函数。
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);
}
system_clock::period
向时钟询问其提供的精度。 - Nicol Bolas