為什麼移動鼠標光標會導致Windows 95運行更快?


404

我正在玩Hypnospace Outlaw,這是一個有關復古主題OS的遊戲。該操作系統具有一種特殊的行為,即在加載網頁時,擺動鼠標光標可以更快地加載頁面。

那使我想起了什麼。在我小的時候,如果我沒記錯的話,Windows 95(如果不是98)就具有這種奇怪的行為,即在安裝程序時,擺動鼠標光標可以使進度更快。是什麼原因造成的?我用谷歌搜索,找不到任何相關內容。

對於模糊的解釋表示抱歉。

103

Yes, it's a real effect resulting in causing a measurable speed up and can be reproduced at will:

Try opening a large file with Notepad on a contemporary machine. The window must not be full screen. When loaded, mark all text using the mouse (the keyboard works as well, it just needs more manual skill). While still holding the button down (and marking) move the mouse down, so the text gets marked and scrolled. Now compare the scroll speed while holding the mouse still versus wiggling it. Depending on your machine the speed up can be several times faster.

Amazing, isn't it?

It can be viewed in many other programs as well, Notepad is just an easy to reproduce example. It's related to the way multitasking worked in early versions of Windows. Here everything revolved around the message queue. Wiggling the mouse resulted in a flood of mouse-move messages, which in turn made programs wake up more often and (depending on their structure) updating their states each time, going into the message loop again, giving time to screen updates, resulting in an over all faster reaction. It shows a glimpse of the ways MS used to make Windows rather responsive despite its cooperative threaded nature.


470

This is because of a flaw in the way Windows 95 generates events, and the fact that many applications are event driven.

Windows 95 applications often use asynchronous I/O, that is they ask for some file operation like a copy to be performed and then tell the OS that they can be put to sleep until that operation finishes. By sleeping they allow other applications to run, rather than wasting CPU time endlessly asking if the file operation has completed yet.

For reasons that are not entirely clear, but probably due to performance problems on low end machines, Windows 95 tends to bundle up the messages about I/O completion and doesn't immediately wake up the application to service them. However, it does wake the application for user input, presumably to keep it feeling responsive, and when the application is awake it will handle any pending I/O messages too.

Thus wiggling the mouse causes the application to process I/O messages faster, and install quicker. The effect was quite pronounced; large applications that could take an hour to install could be reduced to 15 minutes with suitable mouse input.


-2

Windows pre-NT (Windows 1,2,3,3.11,95,98) was cooperative multitasking vs NT's (2000, XP, Vista, 7 & 10) preemptive multitasking.

On cooperative multitasking, the foreground app has to yield control to other tasks. Thus if the foreground app got stuck, the whole machine froze.

Preemptive multitasking, the system usually had a hardware interrupt, usually a timer, to force a yield.

On Windows 95, the keyboard and mouse generated interrupts, moving the mouse caused the interrupt to fire and the OS to service it's event queue. A form of preemptive multitasking, instead of a fixed timer interrupt, you were doing it.

The OS would update the status on screen at the interrupt and then go service the other tasks. The screen update would make it seem that the OS was processing faster.

EDIT - 1/2 right ... Cannot pre-emptively multitask Win16 applications because it uses the same System Virtual Machine (VM) model as in Windows 3.1 to run Win16 applications. Thus, Windows 95 will revert to a cooperative multitasking environment when running Win16 applications and give them exclusive control of the CPU for as long as the applications are executing. As a result, true pre-emptive operation is impossible when multitasking a mixture of Win16 and Win32 applications.


38

It wasn't just Windows 95, but Windows 3.x as well, even though they work very differently.

Other answers talk about pre-emptive multitasking, so let's first clarify this:

Window 3.x was using cooperative multitasking where each app would release the cpu for the other apps to use it. Windows 95 uses pre-emptive multitasking where each app is allocated a time slice.

The answer is linked to how the graphic interface works: in a windows graphical app, there is a loop called the 'message pump':

Every event (mouse moved, window got resized, etc) is pushed into a queue. The app is responsible to check if it has messages waiting and, if yes, pull them and process them.

This is at this moment that Windows 3.x was switching to other apps since there was a single point where all apps where going to, but this doesn't apply to windows 95.

What really happens is that, on both OS, you need to process the message loop, but if you want to update something in the background, like a task, a display update, etc, you'd set a timer and the timer would put a message in the queue at a regular interval.

These were better ways to do things on Windows 95, but developers took time to transition from Windows 3.x and many apps were structured the same.

Since the main mechanism was to rely only on the message loop and background operations were done through timer messages, moving the mouse would trigger a lot of messages, move the app up in priority, wake the app up, and get the app to process the background tasks messages. Without moving the mouse, the timer messages would be read up only at a rather slow interval.

The most famous app for this was the disk defragmenter where operations would wait for a message to update the graphic interface! so shaking the mouse would speed up the defrag.


13

Arguably, this is a common bug in early software based on an event-processing loop rather than a Windows bug: if some DD-paths of the loop only process a single event, then every time when two events are generated simultaneously, only one is processed and the other gets stuck. Moving the mouse generates more incoming events and restarts the loop. "Mouse move" events are typically processed by a GUI library, which handles them correctly (that is, processing all such events in the queue), so those events help get the loop going, and then disappear harmlessly.

Such bugs are easily missed when the testing is done by hand, since the act of testing itself generates enough input events to keep the bug hidden.


25

The reason is because of how WM_TIMER is limited to 15.6ms intervals by default. If you call SetTimer() with a 1ms interval it will still be called in 15.6ms intervals. WM_TIMER drives a lot of stuff in Win32 applications like network packet processing and such.

Moving the mouse causes WM_TIMER events to fire more often on Win95. So some applications will seem to run faster.

The 15.6ms value was set for various reasons: Not clogging up the event queue so that stuff like WM_PAINT would still dispatch often enough and more recently and importantly to save power. There are tons of articles talking about this:

https://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/


19

Raymond Chen from Microsoft has a great answer on his blog:

One danger of the MsgWaitForMultipleObjects function is calling it when there are already messages waiting to be processed, because MsgWaitForMultipleObjects returns only when there is a new event in the queue.

His blog is a great read!


3

Quick answer, by moving the cursor you were telling windows that you are the most important event running. When you stop interacting windows gives priority to other events. So installing programs even when in foreground would give priority to less important events. This bug is no longer present in current Windows versions.