Home > Article > System Tutorial > Exploring context switching on Linux CPUs
As we all know, Linux is an operating system that supports multitasking. The number of tasks it can run at the same time far exceeds the number of CPUs. Of course, these tasks are not actually running at the same time (for a single CPU), but because the system allocates the CPU to these tasks in turn for a short period of time, creating the illusion of multiple tasks running at the same time.
Before each task runs, the CPU needs to know where to load and start the task. This means that the system needs to set the CPU's registers and program counter in advance.
CPU registers are small but very fast pieces of memory built into the CPU. The program counter is used to store the location of the instruction currently being executed by the CPU or the location of the next instruction to be executed.
Both of these are the necessary environments for the CPU before executing any tasks, so they are called "CPU context". Please refer to the picture below:
Now that you know what the CPU context is, I think it will be easy for you to understand CPU context switching. "CPU context switch" refers to saving the CPU context (CPU registers and program counter) of the previous task, then loading the context of the new task into these registers and program counter, and finally jumping to the program counter.
These saved contexts are stored in the system kernel and loaded again when task execution is rescheduled. This ensures that the original state of the task is not affected and the task appears to be running continuously.
You might say that CPU context switching is nothing more than updating CPU registers and program counter values, and these registers are designed to run tasks quickly, so why does it affect CPU performance?
Before answering this question, have you ever thought about what these "tasks" are? You might say that a task is a process or a thread. Yes, processes and threads are the most common tasks, but there are other types of tasks besides that.
Don’t forgetHardware interrupt is also a common task. The hardware trigger signal will cause the interrupt handler to be called.
Therefore, there are at least three different types of CPU context switches:
Let’s take a look one by one.
Linux divides the running space of the process into kernel space and user space according to the privilege level, which correspond to the CPU privilege levels of Ring 0
and Ring 3
in the figure below respectively.
Ring 0
) has the highest permissions and can directly access all resourcesRing 3
) can only access restricted resources and cannot directly access hardware devices such as memory. It must be trapped into the kernel via a system call in order to access these privileged resources. Looking at it from another perspective, a process can run in both user space and kernel space. When a process is running in user space, it is called the user state of the process. When it falls into kernel space, it is called the ## of the process. #kernelstate.
The conversion from user mode to kernel mode needs to be completed through system call. For example, when we view the contents of a file, we need the following system call:
open()
:Open fileread()
: Read the contents of the filewrite()
: Write the contents of the file to the output file (including standard output) close()
:Close the fileSo will CPU context switching occur during the above system call? of course.
This requires saving the location of the original user mode instruction in the CPU register first. Next, in order to execute kernel-mode code, the CPU registers need to be updated to the new location of the kernel-mode instructions. Finally, jump to the kernel state to run the kernel task.
Then after the system call ends, the CPU register needs to restore the original saved user state, and then switch to user space to continue running the process.
Therefore, during a system call, there are actually two CPU context switches.
But it should be pointed out that the system call process will not involve process switching, nor will it involve switching of system resources such as virtual memory. This is different from what we usually call "process context switching". Process context switching refers to switching from one process to another, while the same process is always running during the system call
The system call process is usually called privileged mode switch, rather than context switch. But in fact, during the system call process, CPU context switching is also inevitable.
So what is the difference between process context switching and system calls? First of all, processes are managed by the kernel, and process switching can only occur in kernel mode. Therefore, the process context includes not only user space resources such as virtual memory, stack, and global variables, but also kernel stack and Register and other kernel space status.
So Process context switchingThere is one more step than system call:
Before saving the kernel state and CPU registers of the current process, you need to save the virtual memory, stack, etc. of the process; and load the kernel state of the next process.
According to Tsuna's test report, each context switch requires tens of nanoseconds to microseconds of CPU time. This time is considerable, especially in the case of a large number of process context switches, which can easily cause the CPU to spend a lot of time saving and restoring resources such as registers, kernel stacks, and virtual memory. This is exactly what we talked about in the last article, a significant factor that causes load average to rise.
So, when will the process be scheduled/switched to run on the CPU? In fact, there are many scenarios. Let me summarize them for you:
suspends itself
through the sleep function, it will naturally be rescheduled. It is very necessary to understand these scenarios, because once there is a performance problem with context switching, they are the killer behind the scenes.
The biggest difference between threads and processes is that threads are the basic unit of task scheduling, while processes are the basic unit of resource acquisition.
To put it bluntly, the so-called task scheduling in the kernel actually schedules threads; and the process only provides resources such as virtual memory and global variables for threads. Therefore, for threads and processes, we can understand it this way:
In this way, thread context switching can actually be divided into two situations:
Obviously, thread switching within the same process consumes less resources than switching multiple processes. This is also the advantage of multi-threading instead of multi-process.
In addition to the previous two context switches, there is another scenario that also outputs CPU context switching, which is interrupt.
In order to quickly respond to events, hardware interrupts will interrupt the normal scheduling and execution process, and then call the interrupt handler.
When interrupting other processes, the current state of the process needs to be saved so that the process can still recover from the original state after the interruption.
Unlike process context, interrupt context switching does not involve the user state of the process. Therefore, even if the interrupt process interrupts the process in user mode, there is no need to save and restore user mode resources such as virtual memory and global variables of the process.
In addition, like process context switching, interrupt context switching will also consume CPU. Excessive switching times will consume a lot of CPU resources and even seriously reduce the overall performance of the system. Therefore, when you notice too many interrupts, you need to pay attention to check whether it will cause serious performance problems for your system.
In summary, no matter which scenario leads to context switching, you should know:
CPU context switching is one of the core functions to ensure the normal operation of the Linux system, and generally does not require our special attention.
However, excessive context switching will consume CPU time to save and restore data such as registers, kernel stacks, virtual memory, etc., thus shortening the actual running time of the process and causing a significant decrease in overall system performance.
The above is the detailed content of Exploring context switching on Linux CPUs. For more information, please follow other related articles on the PHP Chinese website!