Windows OS Quantum vs. SQL OS Quantum

Even though the scheduler isn't preemptive, the SQL Server scheduler still adheres to a concept of a quantum. Rahter than SQL Server tasks be forced to give up the CPU by the operating system, they can request to be put on a wait queue periodically, and if they have exceeded the internally defined 4 millisecond quantum and aren't in the middle of an operation that can't be stopped, they voluntarily relinquish the CPU.

-"Microsoft SQL Server 2012 Internals", Kalen Delaney et. al. pp38

-Chapter 2 "The SQLOS" Jonathan Kehayias

So the notion of a "quantum" inside SQL Server is more of a "guideline" for programming tasks. IE when you write a task, like say, a task that performs a table scan, if you don't hit any page latch, IO latch, or lock waits for a while, you should stop what you're doing and ask to be put back on the runnable queue, in case there are other tasks waiting.

But it's up to the task programmer to implement this, and it might not be exactly 4ms for each kind of task. For instance the table scan task might use a simple heuristic based on the number of pages scanned to implement the yield points.

So

The SQL OS starts a quantum (4 ms) and after 3.5 ms, the OS quantum has decided to stop the current SQL OS thread which still has 0.5 ms before it would yield the schedule. What happens now?

If the SQL Server thread is pre-empted by Windows while a task is running, it will be paused, and when its thread is next scheduled on a CPU it will continue where it left off. Presumably it will continue to consume the balance of its 4ms quantum, as it wouldn't know any difference. But again, the yield behavior is an implementation detail of the task, not a behavior of SQLOS, so different tasks might behave differently here.


Answer contributions originally left as comments

How is the SQL Server Quantum (4 ms) synchronised with the Server OS Quantum (normally: 187.5 ms)?

It's not and SQL Server doesn't use preemptive scheduling. Work items are expected to hit yield points and if they don't, you get things such as NONYIELDING schedulers. There is no parity. SQL Server doesn't distribute the time. It makes certain threads attractive to Windows to schedule and Windows schedules them. Quantum is just nomenclature for a piece of time. That's it. SQL Server isn't preemptive, it's the responsibility of whatever is running to yield itself throughout the code. – Sean Gallardy

When the OS quantum expires the thread is forcefully descheduled. This is transparent to SQL Server. SQLOS has no way of detecting when this happens. There is no Win32 API for that. Scheduling is transparent to user mode threads. The Windows scheduler does not know or care what user mode threads are doing. Windows only sees threads that are runnable and lets them run till the end of their OS quantum or until they block. – usr

In How to handle excessive SOS_SCHEDULER_YIELD wait type values in SQL Server by Nikola Dimitrijevic, the term "quantum" is used to mean essentially "the time a task actually spends assigned to a worker", but that's not the same sense as a Windows quantum, which is a period of time after which the OS will remove a thread from a CPU. They're just different concepts. If the OS forces a thread to end execution because the OS quantum has been reached, a context switch happens. SQL Server's thread is suspended, just like any other program. – David Browne - Microsoft and George.Palacios.


Extracts from the documentation: Inside the SQL Server 2000 User Mode Scheduler (written for SQL Server 2000, but still relevant):

Preemptive vs. Cooperative Tasking

UMS, by contrast, relies on threads to yield voluntarily. UMS takes the approach it does in order to keep from involving the Windows kernel any more than absolutely necessary. In a system where worker threads can be counted on to yield when they should, a cooperative scheduler can actually be more efficient than a preemptive one because the scheduling process can be tailored to the specific needs of the application. As I said earlier, UMS knows the scheduling needs of SQL Server better than the operating system can be expected to.

How UMS Takes Over Scheduling

If UMS is to handle SQL Server's scheduling needs rather than allowing Windows to do so, UMS must somehow prevent the OS from doing what it does with every other process: schedule threads on and off the system's processor(s) as it sees fit. How do you do that in a preemptive OS? UMS pulls this off through some clever tricks with Windows event objects. Each thread under UMS has an associated event object. For purposes of scheduling, Windows ignores threads it does not consider viable—threads that cannot run because they are in an infinite wait state. Knowing this, UMS puts threads to sleep that it does not want to be scheduled by having them call WaitForSingleObject on their corresponding event object and passing INFINITE for the timeout value.

In order to prevent Windows from scheduling multiple threads on the same processor and thereby incurring the overhead and expense of context switches, UMS attempts to keep just one thread viable—that is, not in an infinite wait state—per processor.

Tags:

Sql Server