自从之前有一篇文章因操作不顺手导致丢失,就不敢来随便长篇大论了。今天稍微写一点,总结WindowsAPI里两个宝贝函数QueryPerformanceCounter()和QueryPerformanceFrequency()的用法。
用到这两个函数是因为今天在优化软件渲染器的代码,要精确测试每个函数运行时间。写了这么多年程序了,在计时之类的功能上,我就一直在用那个GetTickCount(),从来没有用过更好的,感觉自己真是菜的可以o(╯□╰)o.要精确测试函数甚至代码块的运行时间,GetTickCount()精度远远不够,基本上是测不出来,只能用传说中的“高精度性能计数器”。
起初不会用,就看了一下MSDN文档,大概明白了意思,QueryPerformanceFrequency用来获得“高精度性能计数器”的频率,这个“高精度性能计数器”也不知是个什么东西,运行代码测试,发现数值是和CPU的主频相等,如此一来倒是可以用来测CPU的速度了,是不是任何硬件环境里这个”高精度性能计数器”频率都和CPU频率一样?文档里没说,不知是否有其它情况。
然后再看QueryPerformanceCounter参考,是用来获得“高精度性能计数器”当前走过的计时次数,难道是从开机以来?用代码测试发现我的猜想好像是正确的,是个超大的整数。这个函数很有意思,文档特别提醒在多核处理器上,这个值可能随机来自任何一个核心?这样可怎么测啊,又说引起这个问题的原因是BIOS和HAL,不是所有硬件都有这个问题,跟具体硬件有关。好吧,我殷切的希望我用的电脑解决这个问题了。文档给出了一个勉强的解决方法,就是对调用线程设置ProcessorAffinity,用SetThreadAffinityMask()函数,我想还是不予考虑了。用代码测试了一下,发现不设置ProcessorAffinity没太大影响,也许是CPU自动均衡了不同核心的时间的缘故。
最后就诞生了一个典型的用法,用QueryPerformanceFrequency在程序初始化时获取到那个近似CPU频率的计数频率,在需要检测的代码段的前后调用两次QueryPerformanceCounter,最后计算出代码执行的频率,比如测渲染的帧速:
&nb