11.13
Windows 2000 中还新增加了一个 void GetSystemTimeAsfileTime(fiLETIME*) 函数,它
会返回一个自 1601 年 1 月 1 日 00:00 UTC 开始计算的以 100 纳秒为时标的计数值。其中,
fiLETIME 也是一个带有 64 位整数的结构体,不过这次是无符号的形式。尽管该时标计数
器显示出来的分辨率看起来非常高,有些实现却使用了与 GetTickCount() 所使用的低分辨
率计数器相同的计数器。
很快,QueryPerformanceCounter() 的更多问题暴露出来了。有些处理器实现了可变时钟
频率来管理功耗。这会导致时标周期发生了变化。在拥有多个独立处理器的多处理器系统
中,QueryPerformanceCounter() 返回的值取决于线程运行于哪个处理器之上。处理器开
始实现指令重排序之后,导致 RDTSC 指令可能会发生延迟,降低使用了 TSC 的软件的
准确性。
为了解决这些问题,Windows Vista 为 QueryPerformanceCounter() 使用了一种不同的计
数器,称为 Advanced Configuration and Power Interface(ACPI)电源管理计时器。使用
这个计数器虽然能够解决多处理器的同步问题,但是却显著地增加了延迟。与此同时,
英特尔重新指定了 TSC 为最大且不变的时钟频率。此外,英特尔还增加了不可重排序的
RDTSCP 指令。
自 Windows 8 开始,Windows 提供了一种基于 TSC 的、可靠的、高分辨率的硬件时标计
数。只要该系统运行于 Windows 8 或者之后的版本上,void GetSystemTimePreciseAsfileT
ime(fiLETIME*) 就可以生成一个固定频率和亚微秒准确度的高分辨率时标。
会返回一个自 1601 年 1 月 1 日 00:00 UTC 开始计算的以 100 纳秒为时标的计数值。其中,
fiLETIME 也是一个带有 64 位整数的结构体,不过这次是无符号的形式。尽管该时标计数
器显示出来的分辨率看起来非常高,有些实现却使用了与 GetTickCount() 所使用的低分辨
率计数器相同的计数器。
很快,QueryPerformanceCounter() 的更多问题暴露出来了。有些处理器实现了可变时钟
频率来管理功耗。这会导致时标周期发生了变化。在拥有多个独立处理器的多处理器系统
中,QueryPerformanceCounter() 返回的值取决于线程运行于哪个处理器之上。处理器开
始实现指令重排序之后,导致 RDTSC 指令可能会发生延迟,降低使用了 TSC 的软件的
准确性。
为了解决这些问题,Windows Vista 为 QueryPerformanceCounter() 使用了一种不同的计
数器,称为 Advanced Configuration and Power Interface(ACPI)电源管理计时器。使用
这个计数器虽然能够解决多处理器的同步问题,但是却显著地增加了延迟。与此同时,
英特尔重新指定了 TSC 为最大且不变的时钟频率。此外,英特尔还增加了不可重排序的
RDTSCP 指令。
自 Windows 8 开始,Windows 提供了一种基于 TSC 的、可靠的、高分辨率的硬件时标计
数。只要该系统运行于 Windows 8 或者之后的版本上,void GetSystemTimePreciseAsfileT
ime(fiLETIME*) 就可以生成一个固定频率和亚微秒准确度的高分辨率时标。
一句话总结本堂历史课的内容就是,PC 从来都不是设计作为时钟的,因此它们提供的时
标计数器是不可靠的。如果以过去 35 年的历史为鉴,未来的处理器和操作系统可能依然
无法提供稳定的、高分辨率的时标计数值。
历 代 PC 都 提 供 的 唯 一 可 靠 的 时 标 计 数 器 就 是 GetTickCount() 返 回 的 时 标 计 数 器
了, 尽 管 它 也 有 缺 点。clock() 返 回 的 毫 秒 级 的 时 标 更 好, 而 且 近 10 年 生 产 的 PC
应 该 都 是 支 持 该 函 数 的。 如 果 只 考 虑 Windows 8 及 之 后 的 版 本 和 新 的 处 理 器 的 话,
GetSystemTimePreciseAsfileTime() 返回的 100 纳秒级别的时标计数器是非常精确的。不
过,就我个人的经验来看,对时间测量来说毫秒级别的准确性已经足够了。
标计数器是不可靠的。如果以过去 35 年的历史为鉴,未来的处理器和操作系统可能依然
无法提供稳定的、高分辨率的时标计数值。
历 代 PC 都 提 供 的 唯 一 可 靠 的 时 标 计 数 器 就 是 GetTickCount() 返 回 的 时 标 计 数 器
了, 尽 管 它 也 有 缺 点。clock() 返 回 的 毫 秒 级 的 时 标 更 好, 而 且 近 10 年 生 产 的 PC
应 该 都 是 支 持 该 函 数 的。 如 果 只 考 虑 Windows 8 及 之 后 的 版 本 和 新 的 处 理 器 的 话,
GetSystemTimePreciseAsfileTime() 返回的 100 纳秒级别的时标计数器是非常精确的。不
过,就我个人的经验来看,对时间测量来说毫秒级别的准确性已经足够了。