致电DateTime.Now
时会发生什么?
我按照Reflector中的属性代码,它似乎将当前区域设置的时区偏移添加到UtcNow
。在UTCNow
引导我之后,轮流转向,最后转到Win32 API调用。
我反思并问a related question但尚未得到满意的答复。从目前评论中关于该问题的链接,我推断有一个硬件单元可以保留时间。但我也想知道它保留了什么单位以及它是否使用CPU将时间转换为人类可读单元。这将揭示日期和时间信息的检索是I / O绑定还是计算绑定。
答案 0 :(得分:35)
对于这个问题,你处于无证领域。时间由内核提供:底层本机API调用是NtQuerySystemTime()
。这个确实在Windows版本中被修改 - Windows 8特别严重地改变了底层实现,带来了明显的副作用。
本质上是I / O限制:时间由RTC(实时时钟)维护,RTC曾经是专用芯片,但现在集成在芯片组中。但是有很强的证据表明它在实践中不受I / O约束。时间更新与时钟中断同步,因此中断处理程序很可能会读取RTC并获得值的副本。当您修改timeBeginPeriod()
时,您可以看到一些东西。
您可以看到,当您对其进行分析时,它在Windows 10上只需要约7纳秒 - 完全太快而无法进行I / O限制。
答案 1 :(得分:4)
你似乎关心阻拦。有两种情况你想避免这种情况。
UtcNow
超级快,所以不是一个问题。UtcNow
这个问题没有实际意义。你只需按原样调用它。由于Windows上的时间通常以60 Hz的速度前进,因此我假设对UtcNow
的调用是从写入60 Hz的内存变量中读取的。这使得CPU受到限制。但这两种方式无关紧要。
答案 2 :(得分:3)
.NET依赖于API。 MSDN必须说明API:
https://msdn.microsoft.com/de-de/library/windows/desktop/ms724961(v=vs.85).aspx
当系统首次启动时,它会根据计算机的实时时钟将系统时间设置为一个值,然后定期更新时间[...] GetSystemTime将时间复制到SYSTEMTIME [...]
我找不到可靠的来源来支持我声称它存储为SYSTEMTIME
结构,在其中更新,并在调用时被复制到GetSystemTime
的接收缓冲区。最小的逻辑单位是NtQuerySystemTime系统调用的100ns,但我们最终在CLR的DateTime
对象中有1毫秒。分辨率并不总是相同的。
我们或许可以在Linux上为Mono弄清楚这一点,但鉴于API代码本身并不公开,我们很难为Windows解决这个问题。所以这是一个假设:当前时间是内核地址空间中的变量。它将由操作系统更新(通常由系统时钟计时器中断,更不频繁地来自网络源 - 文档提到呼叫者可能不依赖于单调行为,因为网络同步可以向后纠正当前时间)。操作系统将同步访问以防止并发写入,否则它将不会是I / O昂贵的操作。
在最近的计算机上,定时器间隔不再固定,可以由BIOS和OS控制。应用甚至可以请求更低或更高的时钟频率:https://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted