There are tons of resources about context switching online. Let me quickly give you a primer about context switching before we go to voluntary & involuntary context switch.
We use multicore CPU machines. Each core works as an independent unit & can execute instructions sequentially. So if a machine has four cores, it should be able to execute 4 different instruction set simultaneously. Programs or processes are nothing but instruction sets. So we can run four different processes parallelly. All is good till now. But now we have started 12 programs at the same time. Obviously 4 CPU units can’t run 12 different instruction sets at the same time. That’s where context switch comes into picture.
For simplicity, we can define the above problem with one CPU core & two processes. How does two processes get executed simultaneously in a single CPU? It is not possible, so CPU divides time between the two processes. Every computer hardware has its own clock, it may be a timer chip. This timer chip keeps on interacting with the CPU after certain interval, typically in order of milliseconds like every millisecond. This interaction is called timer interrupt. The time interval is mostly defined by the operating system installed. When OS is running two processes in a single CPU, below steps happen under the hood:
- Process A & process B both are in ready state. OS scheduler picks process A for execution. OS scheduler is a kernel level program which decides what task or process to run next.
- CPU starts executing process A. Process A is in running state.
- After 1 millisecond, CPU gets a timer interrupt.
- CPU checks for corresponding interrupt handler. It gets interrupt handler instruction location from kernel address space.
- In this case, timer interrupt handler invokes OS scheduler.
- OS scheduler knows that there is another process B which is waiting for CPU cycle & in ready state.
- OS scheduler saves process A context (CPU register & program counter) & puts process A back in ready state. CPU register contains state information of process A & program counter points to the next instruction to be executed. This information is saved in RAM.
- OS scheduler puts process B in running state. CPU starts executing process B.
- After 1 millisecond, CPU gets a timer interrupt.
- CPU checks timer interrupt handler.
- Timer interrupt handler again invokes OS scheduler.
- OS scheduler knows that process A is in ready state.
- OS scheduler saves process B context & put it back to ready state.
- OS scheduler loads process A context from main memory to CPU.
- OS scheduler brings process A to running state & CPU starts executing it from where it left.
The above process goes on till both process A & process B are finished. The saving of context of a process to main memory & loading context of another process to CPU from main memory is what we call as context switch. It is an additional but necessary overhead.
Now let’s talk about voluntary & involuntary context switch & the difference between them. The explanation that I have given above uses timer or clock interrupt with a round robin scheduling algorithm. But there are different types of hardware & software interrupts. Also as processes wait for I/O or user input, they can be put to waiting state & thus CPU cycle gets freed up for other processes.
Voluntary context switch occurs when a process yields CPU cycles on its own. It may be because the process was finished before the timer interrupt was invoked. Or a process was waiting on I/O or sleeping. So OS kernel put it to waiting state as there was no instruction to execute in CPU. OS kernel will put the process back to ready state when I/O operation is done or process awakes from sleep. OS scheduler will put it to running state eventually. Voluntary context switch occurs when there is no instruction to execute for that process at the moment.
Involuntary context switch is the opposite. A process is running & its instruction set is getting executed on the CPU. But OS scheduler decides to put it back to ready state & remove it from active CPU cycle. The scenario I described above with process A & process B is an example of involuntary context switching. Both processes were competing on a single CPU unit & OS scheduler was trying to divide time fairly between the two processes.
Voluntary context switching is not something that you should worry about. But too many involuntary context switches is a cause of concern. Context switching takes additional time. Total time for a process is time taken to complete instruction set plus context switch time. That’s why if you create too many processes & execute it in normal multicore system, you might not get optimal execution time. Processes might take longer time to complete as there would be too many context switches happening. So as a developer, we need to be careful about choosing the number of parallelism we want to create based on the machine configuration. It should be benchmarked.