为什么移动鼠标会让操作系统跑得更快?
作者丨InfoQ
译者丨无明
策划丨小智
在玩 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,更重要的是可以节能。有很多文章提到了这个,比如这篇:
https://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/。
可以说,这个问题在早期基于事件循环的软件系统上是很常见的,并不是 Window 的 bug。如果事件循环每次只处理一个事件,当同时生成两个事件时,只有一个事件会被处理,另一个会被阻塞。不断移动鼠标会生成更多的事件,这样就可以重新进入循环。鼠标移动事件通常是由专门的 GUI 库负责处理的,这些事件被用来重启循环,然后丢掉。
在进行手动测试时很容易就把这个 bug 忽略掉了,因为测试本身会生成足够多的事件,无法发现这个 bug。
简单地说就是:你通过移动鼠标告诉操作系统当前的应用程序事件是最重要的。如果鼠标停止移动,操作系统就会把优先级分配给其他事件。所以,即使是在安装程序,操作系统也有可能把优先级分配给不重要的事件。不过,这个 bug 在后续的 Windows 版本中已经不存在了。
原文链接:
https://retrocomputing.stackexchange.com/questions/11533/why-did-moving-the-mouse-cursor-cause-windows-95-to-run-more-quickly
点个在看少个 bug 👇
- VMWARE中虚拟工具VMTOOLS的安装 安装 vmtools之前,需要先打开虚拟机,并且启动其中的操作系统。 注意看下图中鼠标的位置。请将鼠标移动到相应位置上点击右键。 在弹出的菜单最下端点击“
- 操作系统内核开发:输入文本框和鼠标移动窗体
- 为什么在移动互联设备上会有这么多操作系统
- unity 根据鼠标的移动来旋转物体Rotate
- js实现div跟谁鼠标悬浮移动显示
- Qt实现当鼠标移动到窗体上,窗体由半透明变为不透明
- 解决Ubuntu安装VMware tools后鼠标指针平滑移动问题
- 小球随鼠标移动
- [c.y.j]js 鼠标移动事件
- 使用远程桌面鼠标移动缓慢问题的解决
- MFC 学习之 鼠标移动到Toolbar按钮上显示提示信息(tooltip),状态栏也随之改变
- 鼠标在文本上移动时层的显示与消失
- 鼠标移动太快,mouseout事件不触发解决方案
- Java实现鼠标拖拽移动界面组件
- 鼠标移动到指定位置显示网页内容,鼠标移出隐藏
- OSG学习笔记16 - 对点选物体平移(鼠标点选物体)(物体随鼠标移动)(屏幕坐标转世界坐标)
- [Unity]Object跟随鼠标移动而旋转
- HTML样式中移动鼠标到指定位置改变光标形状
- js 自动滚动,鼠标移动停止滚动
- jquery实现表格随着鼠标的移动而显示亮色