标题:关于Windows定时器精度和Sleep(1)的讨论
总结一下
- 要测试耗时需要正确的环境,比如关闭控制台输出、NLOG异步设置和buffsize、系统区分(windows还是linux)、客户端还是服务端、内网还是外网、TCP、KCP等因素。
- Allserver一个消息全在一个线程中转,当然多点时间,gate进程发个消息给map才是内网耗时。
- 服务端Sleep(1),并不是代表休息1ms,具体精度看操作系统。(windows约15ms,linux约1ms)
要在windows上测试需要将全局设置高精度计时器 timeBeginPeriod(1),有些别的软件开启时会设置全局的精度。
相关帖子: 关于Console控制台输出性能差的问题
相关资料
Windows计时器分辨率:重大规则更改
首先,介绍一些操作系统设计上下文。希望程序能够进入睡眠状态,然后稍后再唤醒。实际上,这不应该经常执行-线程通常应该等待事件而不是计时器-但有时这是必要的。因此,我们有了Windows睡眠功能–将其传递给您所需的午睡时间(以毫秒为单位),然后将您唤醒,如下所示:
值得暂停一下,以考虑一下它是如何实现的。理想情况下,当调用Sleep(1)时,CPU会进入睡眠状态,以节省电量,因此,如果CPU处于睡眠状态,操作系统(OS)如何唤醒您的线程?答案是硬件中断。操作系统对计时器芯片进行编程,然后该计时器芯片触发中断以唤醒CPU,然后操作系统可以调度线程
计时器中断之间的间隔取决于Windows版本和您的硬件,但在我最近使用的每台计算机上,默认间隔为15.625毫秒(1,000毫秒除以64)。这意味着,如果您在某个随机时间调用Sleep(1),那么将来每当下一个中断触发时(或者如果下一个中断过早,则在此之后触发),您可能会在1.0毫秒至16.625毫秒之间的某个时间被唤醒。 。
任何程序都可以调用timeBeginPeriod,它会更改计时器中断间隔,并且计时器中断是全局资源。
配置系统以实现高精度
Windows 10 和 Windows Server 2016 中的时间同步已大幅改善。 在合理的操作条件下,可将系统配置为维持 1ms(毫秒)的精度或更高的精度(相对于 UTC)。虽然 Windows 10 或 Windows Server 2016 上支持高达 1 ms 的精度,但大多数客户并不需要高度精确的时间。
因此,默认配置旨在满足与先前的操作系统相同的要求
达到高精度目标需要进行系统配置。 可以通过多种方式来执行此配置,包括直接在注册表中执行或通过组策略。 有关这些设置的详细信息,请参阅 Windows 时间服务技术参考 Windows 时间服务工具。
博客:C#中精确计时的一点收获
// 常用于多媒体定时器中,与GetTickCount类似,也是返回操作系统启动到现在所经过的毫秒数,精度为1毫秒。
[DllImport("winmm")]
static extern uint timeGetTime();
// 一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度
[DllImport("winmm")]
static extern void timeBeginPeriod(int t);
[DllImport("winmm")]
static extern void timeEndPeriod(int t);
// 用法
timeBeginPeriod(1);
uint start = timeGetTime();
Thread.Sleep(2719);
Console.WriteLine(timeGetTime() - start); //单位毫秒
timeEndPeriod(1);
Windows Timer Resolution: Megawatts Wasted
Windows 上的默认计时器分辨率为 15.6 毫秒——每秒中断 64 次。当程序增加计时器频率时,它们会增加功耗并损害电池寿命。它们还浪费了比我预期更多的计算能力——它们使您的计算机运行得更慢!由于这些问题,Microsoft 多年来一直告诉开发人员不要增加计时器频率。
为了获得最长的电池寿命,当前的计时器间隔(可以用timeBeginPeriod或 NtSetTimerResolution 更改)应为 15.6 毫秒。但是正如您在上面看到的,某些程序已将其设置为 1.0 毫秒。这意味着计时器中断每秒额外触发 936 次,只有在收益与成本相称时才应该这样做。
how to set timer resolution from C# to 1 ms?
我使用过这个工具并注意到我的 Windows Server 2008 R2 Standard 的分辨率为 15 毫秒,而 Windows 8 的分辨率计时器为 1 毫秒。我找到了这篇msdn 文章,但它没有解释如何从 C# 程序更改计时器分辨率。我怎么做?
群聊天记录

