[原创分享]关于1ms精度的计时延时器的基本测试

bcrun 2013-10-31 03:25:20
加精
2013年11月30日补充
之前写这篇文章时,因为已经使用win7一段较长的时间,所以没针对API帮助提到的Period方面的精度控制,在WinXP系统下做测试,后来找时间测试了下,不加timeBeginPeriod的话,那两个API在XP下精度远不到1ms。当初写这篇文章的主要目的,是闲聊一下自己测试代码执行速度的一些办法。现在打算结帖了,考虑到确实还有不少程序需要在winxp和win2003下使用,而且即使只在WIN7以上系统中运行,按官方的API说明,加上timeBeginPeriod的设置,也更严谨些,毕竟我也没看到哪里说,在WIN7下这个调用是可以省去的,搞不好在有些地方没调用timeBeginPeriod就不够精度呢。唉,不废话了,直接贴补充的代码。对了,有趣的是,加了timeBeginPeriod(1)后,在xp下多次测试那段DoTestSleep的代码,返回值都是2,不像win7下那样是1.

Public Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Public Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long

Private Sub Form_Initialize()
Call timeBeginPeriod(1)
End Sub

Private Sub Form_Terminate()
Call timeEndPeriod(1)
End Sub


注意:这里说的1ms精度,只是指在适当条件(比如说CPU占用率不太高)下,用下述代码实测时,一般能达到的时间上的分辨率。就好像说一个人视力2.0,是指的他在准备充分条件下,去光线等条件符合相关标准的视力测试表前能测到2.0的水准,并不是说他在睡眼矇眬或长时间盯着电脑屏幕,或其它平时常见的生活状态下都能测试出有这个成绩。绝不能理解为“MS的windows系统能保证这些API实际执行时,所有情况都能有1ms的精度”。如果有“准确率”方面的严苛要求,建议多了解实时操作系统(RTOS)方面的知识。本人那方面了解不多,也就不多讨论了。

刚发了篇小博文,特别适合小白,考虑到论坛里很多人不怎么上博客,在这里也宣传一下
http://blog.csdn.net/bcrun/article/details/13772257
关于1ms精度的计时延时器的基本测试

  一般来说,在平时编程中,出于优化代码运行速度等需求,常需要测算时间,这就需要对相关计时函数的精度做一番了解,不能老是糊里糊涂混日子。下面的测试由此而来

  首先,我们需要测出,常用的计时函数中哪个达到了1ms精度。先测GetTickCount

'声明:
Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount" () As Long
'说明
用于获取自windows启动以来经历的时间长度(毫秒)
'返回值
Long,以毫秒为单位的windows运行时间


如果只100000次的话,因为工作量太小,一般会输出0。不过不用担心,我们逐步加大循环次数,多测几次就行了。注意循环次数的跨度不要太大了,可以200000,300000这样的依次增加。这样你会发现,到了某一次,比如说500000,输出值会突然从0跳到16左右。可见这个API的实际精度只有约16ms.



    Private Sub DoTestGetTickCount()  
Dim lTime1&, lTime2&
Dim i&
lTime1 = GetTickCount
For i = 1 To 400000

Next i
lTime2 = GetTickCount
Debug.Print lTime2 - lTime1
End Sub


写到这里时,可能已经有初学者急着要知道1ms精度的函数在哪了,别急,timeGetTime就是了:



    Private Declare Function timeGetTime Lib "winmm.dll" () As Long


测试代码几乎一样。测试结果为,在本人机器上,循环次数在100000时输出值就约为2-3了,次数增加1倍到200000的话,结果为4-5.如果减小到50000,则是1-2.可见,这个计时函数的精度为1ms.



Private Sub DoTestTimeGetTime()
Dim lTime1&, lTime2&
Dim i&
lTime1 = timeGetTime
For i = 1 To 100000

Next i
lTime2 = timeGetTime
Debug.Print lTime2 - lTime1
End Sub


接下来,因为确认了timeGetTime的精度可以达到1ms,我们可以放心测算延时函数sleep的实际精度了,先公布结果,1ms.


    Private Sub DoTestSleep()  
Dim lTime1&, lTime2&
Dim i&
lTime1 = timeGetTime

Sleep 1 'delay 1 ms
lTime2 = timeGetTime
Debug.Print lTime2 - lTime1
End Sub



最后补充说明一下,获取UTC时间的GetSystemTime和相应的SystemTimeToFileTime,实际精度也是1ms
...全文
3560 64 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
64 条回复
切换为时间正序
请发表友善的回复…
发表回复
东方之珠 2013-11-07
  • 打赏
  • 举报
回复
我一般用高精度频率计数器的2个API。
一如既往哈 2013-11-06
  • 打赏
  • 举报
回复
斑竹辛苦了.........
边走边瞧 2013-11-05
  • 打赏
  • 举报
回复
引用 56 楼 PctGL 的回复:
看了好几个帖子,也不知道你们到底在争论什么 这个什么也证明不了,sleep不是用来计时的,用sleep测试时钟精确性非常不恰当 这种测试结果,大概只能表示为系统的繁忙程度 用sleep会导致线程切换,估计那样代码每次的测试结果都不相同,而不相同的原因也有很多种,其中之一是timegettime的精度,另外就是系统内的线程环境,还有就是系统对线程调度的算法问题 总之。。。 这个题目,lz的到底怎么想的用 sleep 测试精度。。。。
是的,你说得没错,俺也是说LZ测试方法有问题。最前面几帖已经有哥们说过Sleep不准,可LZ觉得Sleep(1)在他机器上测试没问题。 后来LZ意识到问题,赶紧修改了首帖,可惜首帖没有说测试方法只具备参考价值,不能作为真实值来用。 所以,建议LZ继续修改首帖,对测试方法进行说明。
zp_any 2013-11-05
  • 打赏
  • 举报
回复
看不是很明白,我是菜鸟。
PctGL 2013-11-05
  • 打赏
  • 举报
回复
引用 55 楼 go_and_see 的回复:
[quote=引用 53 楼 bcrun 的回复:] Re: 52 楼: MS的windows系统不能保证所有情况都能有1ms的精度 我啥时说过“MS的windows系统能保证所有情况都能有1ms的精度”了?我甚至连在"大多数机器"上这种描述都没写。而且我也明确说明了只是在我自己笔记本测试得结果。哈哈,为了防止技术问题的讨论转移到“面子问题”上去,这个就不单独回复了。
首帖改得真快,俺就不多说啥了。 既然讨论技术,那咱不扯面子了。针对下面代码,俺给出测试结论:xp和win7结果不同,不同的硬件配置返回值也不同。修改首帖吧,赶紧的。

    Private Sub DoTestSleep()  
        Dim lTime1&, lTime2&  
        Dim i&  
        lTime1 = timeGetTime  
       
        Sleep 1 'delay 1 ms  
        lTime2 = timeGetTime  
        Debug.Print lTime2 - lTime1  
    End Sub
[/quote] 看了好几个帖子,也不知道你们到底在争论什么 这个什么也证明不了,sleep不是用来计时的,用sleep测试时钟精确性非常不恰当 这种测试结果,大概只能表示为系统的繁忙程度 用sleep会导致线程切换,估计那样代码每次的测试结果都不相同,而不相同的原因也有很多种,其中之一是timegettime的精度,另外就是系统内的线程环境,还有就是系统对线程调度的算法问题 总之。。。 这个题目,lz的到底怎么想的用 sleep 测试精度。。。。
china_jeffery 2013-11-05
  • 打赏
  • 举报
回复
引用 59 楼 zl373946618289 的回复:
[quote=引用 10 楼 china_jeffery 的回复:] Sleep精度可以达到1ms吗?
打cs开个变速齿轮啊,拿刀啊。各种刀杀啊[/quote]
zl289kkk 2013-11-05
  • 打赏
  • 举报
回复
引用 10 楼 china_jeffery 的回复:
Sleep精度可以达到1ms吗?
打cs开个变速齿轮啊,拿刀啊。各种刀杀啊
bcrun 2013-11-04
  • 打赏
  • 举报
回复
引用 26 楼 go_and_see 的回复:
同样觉得不太可能:MS自己都说了它的操作系统不是RTOS,也许你的验证结果在某些场合下是准确的,换个场合就错了。
你的意思是,要是RTOS才会有1ms精度的延时?
边走边瞧 2013-11-04
  • 打赏
  • 举报
回复
引用 37 楼 clever101 的回复:
参考: VC获取精确时间的做法
感谢分享。
边走边瞧 2013-11-04
  • 打赏
  • 举报
回复
引用 33 楼 bcrun 的回复:
[quote=引用 26 楼 go_and_see 的回复:] 同样觉得不太可能:MS自己都说了它的操作系统不是RTOS,也许你的验证结果在某些场合下是准确的,换个场合就错了。
你的理解很成问题,有个1ms的sleep就算RTOS了?也差太远了吧。[/quote] 你的理解能力,呵呵。RTOS在任何场合都能保证时间精度,至于保证多高的精度则是另外一个问题,这个没啥争论吧。你再读一遍俺的原话:也许你的验证结果在某些场合下是准确的,换个场合就错了。 没有歧义吧?真不知道你怎么得出“1ms的时间精度==RTOS”的推论。
边走边瞧 2013-11-04
  • 打赏
  • 举报
回复
引用 53 楼 bcrun 的回复:
Re: 52 楼: MS的windows系统不能保证所有情况都能有1ms的精度 我啥时说过“MS的windows系统能保证所有情况都能有1ms的精度”了?我甚至连在"大多数机器"上这种描述都没写。而且我也明确说明了只是在我自己笔记本测试得结果。哈哈,为了防止技术问题的讨论转移到“面子问题”上去,这个就不单独回复了。
首帖改得真快,俺就不多说啥了。 既然讨论技术,那咱不扯面子了。针对下面代码,俺给出测试结论:xp和win7结果不同,不同的硬件配置返回值也不同。修改首帖吧,赶紧的。

    Private Sub DoTestSleep()  
        Dim lTime1&, lTime2&  
        Dim i&  
        lTime1 = timeGetTime  
       
        Sleep 1 'delay 1 ms  
        lTime2 = timeGetTime  
        Debug.Print lTime2 - lTime1  
    End Sub
nvip 2013-11-04
  • 打赏
  • 举报
回复
RTX是Windows XP的硬实时扩展套件 精确的 clock & timer 确定性的调度for real确定性的调度for real-time threads BUS和 直接访问 I/O, BUS和 内存 注:RTX的应用软件继续执行即使Windows崩溃 RTX的应用软件继续执行即使 的应用软件继续执行即使Windows崩溃
bcrun 2013-11-04
  • 打赏
  • 举报
回复
引用 51 楼 vbvcde 的回复:
1ms精度只有实时系统才有 桌面系统没有 或者安装一个RTOS子系统才可以 windows有实时子系统的软件
能否介绍一下这个“实时子系统的软件” ? Re: 52 楼: MS的windows系统不能保证所有情况都能有1ms的精度 我啥时说过“MS的windows系统能保证所有情况都能有1ms的精度”了?我甚至连在"大多数机器"上这种描述都没写。而且我也明确说明了只是在我自己笔记本测试得结果。哈哈,为了防止技术问题的讨论转移到“面子问题”上去,这个就不单独回复了。
边走边瞧 2013-11-04
  • 打赏
  • 举报
回复
引用 50 楼 bcrun 的回复:
[quote=引用 26 楼 go_and_see 的回复:] 同样觉得不太可能:MS自己都说了它的操作系统不是RTOS,也许你的验证结果在某些场合下是准确的,换个场合就错了。
你的意思是,要是RTOS才会有1ms精度的延时?[/quote] MS的windows系统不能保证所有情况都能有1ms的精度,俺的原话没有歧义,你还是看原话吧。 BTW,掐头去尾得出个武断的推论让俺回答,然后你再找漏洞反击,以便挽回面子,是这个意思吗?你不觉得无聊?
nvip 2013-11-04
  • 打赏
  • 举报
回复
1ms精度只有实时系统才有 桌面系统没有 或者安装一个RTOS子系统才可以 windows有实时子系统的软件
PctGL 2013-11-03
  • 打赏
  • 举报
回复
引用 41 楼 Chen8013 的回复:
... 感觉你没理解我的意思 我是说,在某些情况下 , 他跟精度就没关系, 也就是根本挨不上边,说不上话.... 放一起不合适... 说sleep 的时候最好不要说精度... .
Sarify 2013-11-03
  • 打赏
  • 举报
回复
不错,挺有用的
PctGL 2013-11-03
  • 打赏
  • 举报
回复
引用 43 楼 Chen8013 的回复:
n... 说的是有点过分了,但是目前我对sleep的认识也就到那了。。。 对错与否还待验证,但好在你终于理解我的意思了哈
无主之城 2013-11-03
  • 打赏
  • 举报
回复
非常不错,很好很实用
舉杯邀明月 2013-11-03
  • 打赏
  • 举报
回复
晕,错了一个字。上面的“真实运行机会”应为“真实运行机制”。
加载更多回复(38)

1,488

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧