Winapi 什么是高分辨率性能计数器?

Winapi 什么是高分辨率性能计数器?,winapi,hardware,Winapi,Hardware,在Win32 API中,有一个查询高分辨率性能计时器值的函数QueryPerformanceCounter 什么是“高分辨率性能计时器”?有硬件支持吗?哪些系统不支持它?高分辨率性能计数器通常从rdtsc指令中提取,这是一种特定于x86的方法,用于获取自引导以来发生的CPU周期数。它的值非常精确,通常精确到100ns 将其与GetTickCount()进行比较,后者的精度约为16毫秒 在其他体系结构上(不在Win32 API的范围内,因为它们只在基于x86的指令集上运行),可能有不同的方法来实现

在Win32 API中,有一个查询高分辨率性能计时器值的函数QueryPerformanceCounter


什么是“高分辨率性能计时器”?有硬件支持吗?哪些系统不支持它?

高分辨率性能计数器通常从
rdtsc
指令中提取,这是一种特定于x86的方法,用于获取自引导以来发生的CPU周期数。它的值非常精确,通常精确到100ns

将其与
GetTickCount()
进行比较,后者的精度约为16毫秒


在其他体系结构上(不在Win32 API的范围内,因为它们只在基于x86的指令集上运行),可能有不同的方法来实现这一点。例如,在ARM上,您可以使用系统控制协处理器(CP15)执行类似的操作。

在Windows 7下,在当前一代处理器上,这是CPU(HPET)内可靠的高精度(纳秒)计时器

在以前的版本和前几代处理器上,它是“某物”,几乎可以表示任何东西。最常见的是RDTSC指令(或非x86上的等效指令)返回的值,该值可能可靠,也可能不可靠,且与时钟无关。请注意,RDTSC(最初,根据定义,但现在不再)不测量时间,而是测量周期

在当前和上一代cpu上,RDTSC通常是可靠的,并且与时钟无关(即,它现在实际上是在测量时间),在上一代之前,尤其是在移动或一些多cpu设备上,它不是。“计时器”可能会加速或减速,甚至在不同的CPU上不同,从而导致“时间旅行”

编辑:cpuid(0x8000007)中的
常量tsc
标志可用于判断RDTSC是否可靠(尽管这并不能真正解决问题,因为如果不可靠,如果没有其他选择,该怎么办…)


在更旧的系统(如8-10年前的系统)上,QueryPerformanceCounter可能使用其他一些计时器。这些可能既没有高分辨率,也不是非常准确。

@AlexK.-是的,这最终取决于哈尔。不过,在x86上,我不认为有理由使用rdtsc以外的东西,因为它非常精确。如果我没记错的话,它使用的源时钟与用于运行中断的源时钟相同,而中断的计时准确得可笑。@polyman:请参阅我的答案,了解不应使用RDTSC的原因,除非您保证您的客户不使用可能使用4或5年的CPU。RDTSC只在某些CPU上精确,不一定在所有CPU上精确(而且你不能真正控制你的程序运行在哪个CPU上)。@Polymon:不,你不能,真的。虽然它是精确的,因为它的分辨率为纳秒级,但它并不精确。它与时间没有任何关联,除非它是新一代的CPU。没有准确性的精确就没有意义。如果我给你一个有5000个数字的数字,其中4990个数字是假的,那么这个数字并不比我一开始只给你10个数字好多少(事实上,实际上更糟…。@Damon-非常有趣。似乎真的很难对付!Re:“请注意,RDTSC不测量时间,它测量周期。”,需要注意的是,您可以直接以秒为单位计算时间,如
freq*ticks
@polymone:不,您不能,因为freq!=康斯特。在当今几乎每一个系统(以及过去五年中的大多数系统)上,频率都在动态调整以节省电力。很有趣。还有什么选择?如果1ms的分辨率足够,
timeGetTime
与您从用户进程中获得的分辨率一样好。如果您正在编写驱动程序,可以调用
kequeryintruptime
。如果你需要更高的分辨率,好的替代品是稀疏的。如果您的程序运行的系统具有恒定tsc或HPET,则一切正常。否则你就没有运气了。QPC可以可靠工作,也可以不可靠。