ubuysa
The BSOD Doctor
There are only two Windows controls available to the user that affect application CPU performance, Base Priority and CPU Affinity, and using either of them is more likely to make performance worse rather than better. It is surprisingly easy with these controls to make your whole system sluggish and even hang, forcing a restart. Where these controls are moderately useful is in CPU performance troubleshooting, where they can help to identify which application is causing CPU performance issues. For this reason alone it's worth understanding what these controls do and how best to use them.
Processes and Threads
We think in terms of applications, we start the Chrome browser for example and think of it as one application, but internally it's a bit more complex than that. Applications are managed in Windows as one or more processes and within each process the executing code is managed by one or more threads.
The basic work grouping in Windows is called a process. A process contains all the resources needed for an application to function, each process gets its own virtual address space for example. If you open the Task Manager and click the Details tab every entry you see there is an individual process. Some applications (Notepad for example) run as a single process but other applications (Chrome for example) run as multiple processes.
Within each process the individual units of work are called threads. On the Task Manager Details screen right-click anywhere on the header row and click on 'Select Columns'. In the dialog that opens scroll down and check the box labelled Threads and then click Ok. In this column you can see the number of threads inside each process. A few processes have only one thread - if you have Java installed on your PC then you'll have the Java Update Scheduler process running, it's called jusched.exe, it has only a single thread (it's called a single-threaded process). Now start Notepad (the Task Manager Details page will refresh itself in a few seconds) and look at the thread count for notepad.exe, there are many threads in notepad.exe (this is called a multi-threaded process).
What executes on a CPU are threads, so a multi-threaded process could have several of its threads executing at the same time on different CPUs.
You can find out how many CPUs you have by entering 'msinfo32' in the Run command box, this displays the System Information panel. Make sure the System Summary is selected (it's the default). Look down the Item column in the right-hand pane until you find the Processor entry. That tells you what CPU chip you have and how many cores it has, each core is a separate CPU. If your processor supports hyperthreading, which internally appears to run two threads on each core at the same time, there are two logical processors per core, so a four core processor has eight logical processors. Windows uses logical processors, so on a four core hyperthreading processor Windows will see eight separate CPUs and will run eight threads concurrently, one on each logical processor. If your processor doesn't support hyperthreading then the number of cores is the number of CPUs that Windows will see.
On the Task Manager Details tab look at the Status column, count up how many processes have a status of Running on your system, there are likely well over 100. Even if we assume that each process has only one active thread (and most processes will have more than that) it's clear that we have way more active threads than we have CPUs. How can they all be Running?
Dispatching Threads
A thread exists in one of three states (there are others but they're not important here)...
1. Executing - the thread is executing instructions on a CPU right now
2. Ready - the thread can execute when a CPU becomes available, but it is currently in a queue
3. Waiting - the thread is waiting for some external event to complete and is not able to execute at the moment
In the Task Manager Details page we mentioned above, all those processes with a status of Running have at least one thread that is in one of these states. It means that process is doing work, but not necessarily executing on a CPU right now.
The Windows component that decides which thread to run on which CPU (and when) is called the Dispatcher. The Dispatcher is only interested in threads that are Executing or Ready, a thread that is Waiting is invisible to the Dispatcher.
When a thread moves from the Waiting state to the Ready state it's placed on a queue called the Ready Queue, there is one Ready Queue per logical processor (or per core if your processor doesn't support hyperthreading). The Dispatcher will normally select the thread at the top of the Ready Queue to run on that processor next, so a thread's position on the Ready Queue is critical to it's performance. Threads are queued based on their priority.
Thread Priority
Every thread has a priority from 0 to 31 (where 31 is the highest), this is made up of two components; the base priority and the relative priority.
A thread's base priority is inherited from the process; every process has a base priority which is called either Real-Time, High, Above Normal, Normal, Below Normal, or Low - these names equate to a number (higher numbers mean higher priority). Every thread in a process thus uses the same base priority, this is assigned by the developer based on the relative importance of this process in the whole system.
Each thread also has a relative priority within its process. These are assigned by the developer to establish the relative priorities of the various threads within the process, this is crucial to the proper operation of the process, so only the developer can change these. These have similar names to the base priority but they equate to different numbers, some of them negative numbers.
The relative priority is added to (or subtracted from) the base priority and then capped to give the actual thread priority used to order threads on the Ready Queues. To give you a feel for how the base priority and relative priority are combined to produce the actual priority of a thread the various base priorities produce actual priorities in these ranges....
Low - 1 to 15 but skewed at the low end, mostly around 1 to 6.
Below Normal - 1 to 15 but skewed close to the lower end, mostly around 4 to 8.
Normal - 1 to 15 but skewed in the middle, mostly around 6 to 10.
Above Normal - 1 to 15 but skewed close to the upper end, mostly around 8 to 12.
High - 1 to 15 but skewed at the upper end, mostly 11 to 15.
Real-Time - 16 to 31 but skewed in the middle, mostly 22 to 26.
From this you can see that it is perfectly possible for a thread in a process with Normal base priority to end up with an actual priority that is higher than a thread in a process with the Above Normal base priority. You can also see that the Real-Time base priority always produces an actual priority that is higher than any of the other base priorities.
You can change the base priority of a process but in doing so you change the priority of every thread in that process, from the above you can see that this might produce some unintended consequences for other threads in other processes. Elevating a process to the Real-Time base priority is very likely to have very serious (and probably fatal) consequences for other processes in the system, especially system processes. Don't forget that you have no idea of the relative priority of threads within a process, so you have no idea of the actual priority that each thread in a process will get when you change the base priority of the process.
Open the Task Manager and click the Details tab, if the column labelled Base Priority is not visible then right-click anywhere on the header line, click 'Select Columns', scroll down and check the box labelled Base Priority. In this column you can see the Base Priority assigned to most processes (some System processes run at a fixed priority of 31 and show as N/A in this column). Click the Base Priority column header to sort the processes based on this column, you'll see that you probably have a few High priority processes, a great mass of Normal priority processes and possibly a few Below Normal and even perhaps one or two Low priority processes.
Processes and Threads
We think in terms of applications, we start the Chrome browser for example and think of it as one application, but internally it's a bit more complex than that. Applications are managed in Windows as one or more processes and within each process the executing code is managed by one or more threads.
The basic work grouping in Windows is called a process. A process contains all the resources needed for an application to function, each process gets its own virtual address space for example. If you open the Task Manager and click the Details tab every entry you see there is an individual process. Some applications (Notepad for example) run as a single process but other applications (Chrome for example) run as multiple processes.
Within each process the individual units of work are called threads. On the Task Manager Details screen right-click anywhere on the header row and click on 'Select Columns'. In the dialog that opens scroll down and check the box labelled Threads and then click Ok. In this column you can see the number of threads inside each process. A few processes have only one thread - if you have Java installed on your PC then you'll have the Java Update Scheduler process running, it's called jusched.exe, it has only a single thread (it's called a single-threaded process). Now start Notepad (the Task Manager Details page will refresh itself in a few seconds) and look at the thread count for notepad.exe, there are many threads in notepad.exe (this is called a multi-threaded process).
What executes on a CPU are threads, so a multi-threaded process could have several of its threads executing at the same time on different CPUs.
You can find out how many CPUs you have by entering 'msinfo32' in the Run command box, this displays the System Information panel. Make sure the System Summary is selected (it's the default). Look down the Item column in the right-hand pane until you find the Processor entry. That tells you what CPU chip you have and how many cores it has, each core is a separate CPU. If your processor supports hyperthreading, which internally appears to run two threads on each core at the same time, there are two logical processors per core, so a four core processor has eight logical processors. Windows uses logical processors, so on a four core hyperthreading processor Windows will see eight separate CPUs and will run eight threads concurrently, one on each logical processor. If your processor doesn't support hyperthreading then the number of cores is the number of CPUs that Windows will see.
On the Task Manager Details tab look at the Status column, count up how many processes have a status of Running on your system, there are likely well over 100. Even if we assume that each process has only one active thread (and most processes will have more than that) it's clear that we have way more active threads than we have CPUs. How can they all be Running?
Dispatching Threads
A thread exists in one of three states (there are others but they're not important here)...
1. Executing - the thread is executing instructions on a CPU right now
2. Ready - the thread can execute when a CPU becomes available, but it is currently in a queue
3. Waiting - the thread is waiting for some external event to complete and is not able to execute at the moment
In the Task Manager Details page we mentioned above, all those processes with a status of Running have at least one thread that is in one of these states. It means that process is doing work, but not necessarily executing on a CPU right now.
The Windows component that decides which thread to run on which CPU (and when) is called the Dispatcher. The Dispatcher is only interested in threads that are Executing or Ready, a thread that is Waiting is invisible to the Dispatcher.
When a thread moves from the Waiting state to the Ready state it's placed on a queue called the Ready Queue, there is one Ready Queue per logical processor (or per core if your processor doesn't support hyperthreading). The Dispatcher will normally select the thread at the top of the Ready Queue to run on that processor next, so a thread's position on the Ready Queue is critical to it's performance. Threads are queued based on their priority.
Thread Priority
Every thread has a priority from 0 to 31 (where 31 is the highest), this is made up of two components; the base priority and the relative priority.
A thread's base priority is inherited from the process; every process has a base priority which is called either Real-Time, High, Above Normal, Normal, Below Normal, or Low - these names equate to a number (higher numbers mean higher priority). Every thread in a process thus uses the same base priority, this is assigned by the developer based on the relative importance of this process in the whole system.
Each thread also has a relative priority within its process. These are assigned by the developer to establish the relative priorities of the various threads within the process, this is crucial to the proper operation of the process, so only the developer can change these. These have similar names to the base priority but they equate to different numbers, some of them negative numbers.
The relative priority is added to (or subtracted from) the base priority and then capped to give the actual thread priority used to order threads on the Ready Queues. To give you a feel for how the base priority and relative priority are combined to produce the actual priority of a thread the various base priorities produce actual priorities in these ranges....
Low - 1 to 15 but skewed at the low end, mostly around 1 to 6.
Below Normal - 1 to 15 but skewed close to the lower end, mostly around 4 to 8.
Normal - 1 to 15 but skewed in the middle, mostly around 6 to 10.
Above Normal - 1 to 15 but skewed close to the upper end, mostly around 8 to 12.
High - 1 to 15 but skewed at the upper end, mostly 11 to 15.
Real-Time - 16 to 31 but skewed in the middle, mostly 22 to 26.
From this you can see that it is perfectly possible for a thread in a process with Normal base priority to end up with an actual priority that is higher than a thread in a process with the Above Normal base priority. You can also see that the Real-Time base priority always produces an actual priority that is higher than any of the other base priorities.
You can change the base priority of a process but in doing so you change the priority of every thread in that process, from the above you can see that this might produce some unintended consequences for other threads in other processes. Elevating a process to the Real-Time base priority is very likely to have very serious (and probably fatal) consequences for other processes in the system, especially system processes. Don't forget that you have no idea of the relative priority of threads within a process, so you have no idea of the actual priority that each thread in a process will get when you change the base priority of the process.
Open the Task Manager and click the Details tab, if the column labelled Base Priority is not visible then right-click anywhere on the header line, click 'Select Columns', scroll down and check the box labelled Base Priority. In this column you can see the Base Priority assigned to most processes (some System processes run at a fixed priority of 31 and show as N/A in this column). Click the Base Priority column header to sort the processes based on this column, you'll see that you probably have a few High priority processes, a great mass of Normal priority processes and possibly a few Below Normal and even perhaps one or two Low priority processes.
Last edited: