Archive for July 28th, 2008

Preemptive multitasking vs. Co-operative multitasking

While I’m on this topic, I’ll go ahead and take a brief moment to explain preemptive multitasking versus cooperative multitasking. Back in the bad old days, which wasn’t so long ago for Mac users, the OS relied on each program to give up voluntarily the CPU after its time slice was up. This scheme was called “cooperative multitasking” because it relied on the running programs to cooperate with each other and with the OS in order to share the CPU among themselves in a fair and equitable manner. Sure, there was a designated time slice in which each program was supposed to execute, and but the rules weren’t strictly enforced by the OS. In the end, we all know what happens when you rely on people and industries to regulate themselves–you wind up with a small number of ill-behaved parties who don’t play by the rules and who make things miserable for everyone else. In cooperative multitasking systems, some programs would monopolize the CPU and not let it go, with the result that the whole system would grind to a halt.

Preemptive multi-tasking, in contrast, strictly enforces the rules and kicks each program off the CPU once its time slice is up. Coupled with preemptive multi-tasking is memory protection, which means that the OS also makes sure that each program uses the memory space allocated to it and it alone. In a modern, preemptively multi-tasked and protected memory OS each program is walled off from the others so that it believes it’s the only program on the system.

Our purpose in this article is, “running” does not equal “executing.” I want to set up this terminological distinction near the outset of the article for clarity’s sake. So for the remainder of this article, we’ll say that a program has been launched and is “running” when its code (or some portion of its code) is loaded into main memory, but it isn’t actually executing until that code has been loaded into the processor. Another way to think of this would be to say that the OS runs programs, and the processor executes them. The other thing that I should clarify before proceeding is that the way that I divide up the processor in this and other articles differs from the way that Intel’s literature divides it. Intel will describe its processors as having an “in-order front end” and an “out-of-order execution engine.” This is because for Intel, the front-end consists mainly of the instruction fetcher and decoder, while all of the register rename logic, out-of-order scheduling logic, and so on is considered to be part of the “back end” or “execution core.” The way that I and many others draw the line between front-end and back-end places all of the out-of-order and register rename logic in the front end, with the “back end”/”execution core” containing only the execution units themselves and the retire logic. So in this article, the front end is the place where instructions are fetched, decoded, and re-ordered, and the execution core is where they’re actually executed and retired.