在玩 Hypnospace Outlaw(催眠帝国的法外狂徒)这款游戏时,我发现移动鼠标会让网页加载得更快。
这让我想起了年轻时候用过的 Windows 95,在安装程序时通过移动鼠标可以加快安装速度。这是为什么?我在谷歌上搜索,但找不到相关的信息。
这跟 Windows 95 生成事件的方式有关。很多应用程序是基于事件驱动的。
Windows 95 应用程序通常会使用异步 IO,比如在请求文件操作(例如拷贝文件)时,它会告诉操作系统,然后进入 sleep 状态,直到文件操作结束。一个程序在进入 sleep 状态后,操作系统就把 CPU 让给其他应用程序,而不是一直空等浪费 CPU 时间。
具体原因也不是百分百清楚,但可能是因为 Windows 95 为了解决低配电脑的性能问题对 IO 事件进行”囤积“,即捆绑一系列事件,而不是有事件了就立即唤醒相应的程序。不过,可能是出于响应速度方面的考虑,操作系统一定会唤醒与用户输入有关的程序。
所以,移动鼠标会导致应用程序更快地处理 IO 事件,从而加快了安装速度。这种效果是很明显的,安装一个大型的应用程序可能需要一个小时,但如果在安装过程中不断移动鼠标,可以把安装时间降到 15 分钟。
移动鼠标确实可以达到加快速度的效果,而且可以随意重现。
使用 Notepad 打开一个大型文件,但不要全屏。在加载文件时,使用鼠标标记文本。在保持按住鼠标左键的同时下移鼠标,这样就可以标记更多的文本,而且滚动条会随着鼠标滚动。比较鼠标静止和移动鼠标时的速度,你会发现移动鼠标时速度会更快,具体取决于你的电脑。
很神奇,对吧?
其他应用程序也能重现这样的效果,只是 Notepad 更容易重现。这与早期版本 Windows 多任务处理机制有关。操作系统把事件消息放在队列里,不断移动鼠标会生成很多事件消息,这样就可以频繁唤醒应用程序进行状态更新,重新进入事件循环,从而有更多时间用于屏幕刷新,让整体的反应速度变快。
不仅仅是 Windows 95, Windows 3.x 也会这样,虽然原理不太一样。
有人提到了预分配多任务机制,所以这里先澄清一点:
Windows 3.x 使用的是协作多任务机制,每个应用程序都会释放 CPU 给其他应用程序。Windows 95 使用的是预分配多任务机制,即每个应用程序预先分配了 CPU 时间。
这个与图形界面有关:Windows 图形界面应用程序有一个事件循环,叫作”消息泵“:
每个事件(鼠标移动、缩放窗口,等等)都被推送到一个消息队列中。应用程序负责检查队列中是否有等待的消息,如果有,就把它们拉出来处理掉。
而 Windows 3.x 在这个时候会切换到其他应用程序,因为所有的应用程序都想进入这个点,但在 Windows 95 上不是这样的。
这两个操作系统都需要处理消息循环,如果你想要在后台更新一些东西,比如一个任务或刷新屏幕,需要设置一个定时器,定时器会定时往消息队列中推送消息。
Windows 95 的处理机制会更好一些,但从 Windows 3.x 过渡到 Windows 95 需要时间,所以很多应用程序仍然使用了相同的结构。
因为主要的处理机制仍然依赖于消息循环,而且后台操作也是通过定时器消息来完成的,随意不断移动鼠标会触发更多的事件消息,把应用程序的优先级提高了,在唤醒应用程序后就可以让它处理后台的任务消息。如果鼠标不动,读取定时器消息的间隔会很长。
在这方面最具代表性的是 Windows 磁盘碎片整理程序,磁盘整理操作会等待更新图像界面的消息被处理掉,所以不断移动鼠标会加快碎片整理速度。
主要是因为 WM_TIMER 默认被限制在了 15.6 毫秒。即使你在调用 SetTimer() 时传给它的是 1 毫秒,它仍然会使用 15.6 毫秒。
在 Windows 95 上移动鼠标会更频繁地触发 WM_TIMER 事件,所以应用程序运行得更快。
设定 15.6 毫秒这个限制是有原因的:这样不会阻塞事件队列,可以频繁进行 WM_PAINT,更重要的是可以节能。有很多文章提到了这个,比如这篇:
Windows Timer Resolution: Megawatts Wasted。
可以说,这个问题在早期基于事件循环的软件系统上是很常见的,并不是 Window 的 bug。如果事件循环每次只处理一个事件,当同时生成两个事件时,只有一个事件会被处理,另一个会被阻塞。不断移动鼠标会生成更多的事件,这样就可以重新进入循环。鼠标移动事件通常是由专门的 GUI 库负责处理的,这些事件被用来重启循环,然后丢掉。
在进行手动测试时很容易就把这个 bug 忽略掉了,因为测试本身会生成足够多的事件,无法发现这个 bug。
简单地说就是:你通过移动鼠标告诉操作系统当前的应用程序事件是最重要的。如果鼠标停止移动,操作系统就会把优先级分配给其他事件。所以,即使是在安装程序,操作系统也有可能把优先级分配给不重要的事件。不过,这个 bug 在后续的 Windows 版本中已经不存在了。
Why did moving the mouse cursor cause Windows 95 to run more quickly?
领取专属 10元无门槛券
私享最新 技术干货