为什么QueryPerformanceCounter / QueryPerformanceFrequency失败?

时间:2014-12-02 20:51:07

标签: windows performancecounter

MSDN上有一篇关于QueryPerformanceCounter的文章:

  

Acquiring high-resolution time stamps

接下来是一个FAQ部分,其中有一个有趣的问题:

  

在什么情况下QueryPerformanceFrequency返回FALSE,或QueryPerformanceCounter返回零?

     
    

这不会在任何运行Windows XP或更高版本的系统上发生。

  

答案是正确的,除非是错误的。有 的情况,QueryPerformanceFrequency将返回false

我将自己回答这个问题。

1 个答案:

答案 0 :(得分:1)

  

在什么情况下QueryPerformanceFrequency返回FALSE,或QueryPerformanceCounter返回零?

     

这不会在任何运行Windows XP或更高版本的系统上发生。

这是正确的,也许是措辞的微小变化:

  

可以在运行Windows XP或更高版本的任何系统上发生。

在某些情况下,QueryPerformanceFrequency会返回 false 。对于遇到问题的人,您可以使用Google。

我今天遇到了问题(在Windows 7上):

Int64 freq;
//...
QueryPerformanceFrequency(@freq);

函数调用失败(返回 false ),GetLastError返回:

ERROR_NOACCESS
   998 (0x3E6)
   Invalid access to memory location.

对齐事项

如果您的Int64内存地址不是双字(4字节)对齐,则会出现此问题。例如,如果对对象,结构或类成员变量使用默认为ByteWord对齐的编译器。在这种情况下,QueryPerformanceCounter将返回false。

注意:完全有可能仅QueryPerformanceCounter 发生 才能使用双字(4字节)对齐,might actually require quad-word (8-byte) alignmentWindows x64 calling convention documentation对这个问题保持沉默。

the CPU hardware is silently fixing up 4-byte alignment to 8-byte alignment也可能在1,2,3,5,6或7字节对齐时不会做同样的事情。这种新的驱动系统如果可以操作,也有可能使红十月在大西洋的SOSUS警告网中无法检测到。

TL;博士

  

在什么情况下QueryPerformanceFrequency返回FALSE,或QueryPerformanceCounter返回零?

如果变量不是双字(8字节)对齐,则该函数可能会失败并显示错误代码ERROR_NOACCESS(对内存位置的访问无效)。

Bonus Chatter

文档:

  

返回值

     

如果安装的硬件支持高分辨率性能计数器,则返回值为非零。

     

如果函数失败,则返回值为零。要获取扩展错误信息,请致电GetLastError。在运行Windows XP或更高版本的系统上,该功能将始终成功,因此永远不会返回零。