IT明哥

V1

2022/07/01阅读:16主题:橙心

CPU 上下文切换的机制和类型 (CPU Context Switch)

CPU 上下文切换的机制和类型 (CPU Context Switch)

在上篇介绍零拷贝zero copy的博文中,我们聊到了 CPU 的上下文切换即 CPU Context Switch, 在本片博文中,我们来回顾下 CPU context switch 的概念,机制和具体类型,这将有助于我们进一步理解零拷贝。

1 什么是 CPU context

  • 所谓的 CPU 上下文(CPU contexts),指的是 CPU 处理任务时(任务主要是指进程或线程)需要存储的状态,CPU 在执行任务前,操作系统需要准备好这些上下文,然后 CPU 才知道如何加载和执行任务;
  • CPU 上下文,主要有 CPU 寄存器(cpu registers) 和程序计数器(program counters);
  • CPU 寄存器是 CPU 内部的 memory, CPU 执行指令时并不直接与主存 main memory 交互,而是将主存中的数据拷贝到寄存器 register中再直接与 register 交互:cpu registers are small but extremely fast memory built into the CPU.
  • 程序计数器存储了 cpu 正在执行的指令或将要执行的下一条指令在主存中的地址:program counter is used to store the position of the instruction being executed by the CPU, or the position of the next instruction to be executed;

2 什么是 cpu context switch

  • CPU 上下文切换,即 CPU context switching,是操作系统实现多任务处理的基础 (multitasking),正式CPU上下文切换机制的存在,才使得单颗 CPU 可以并发执行多个任务;
  • CPU 上下文切换时, 首先需要存储当前任务的上下文状态,以便后续可以恢复该任务的状态并继续执行该任务,然后恢复一个先前保存好的任务的上下文状态并继续执行该任务;
  • 由于 CPU上下文切换时涉及到大量状态的保存和恢复,需要消耗大量计算资源,成本较高,所以操作系统和应用程序在设计上需要优化对 CPU Context Switch 的使用;

3 有哪些类型的 cpu context switch

根据触发条件的不同,主要有三种类型的上下文切换:

  • 多任务处理 Multitasking
  • 中断信号处理 Interrupt handling
  • 用户态和内核态切换 User and kernel mode switching

3.1 多任务处理触发的上下文切换 Multitasking

  • Multitasking 是最常见的上下文切换类型,是操作系统调度并并发处理不同任务时触发的上下文切换;
  • 操作系统在多任务分时处理机制下,如果某进程因等待未完成的 IO 操作或其他的同步操作的结果而处于 unrunnable 状态时,会触发 CPU 上下文切换以切换执行其他任务;
  • 操作系统在多任务分时处理机制下,如果某进程仍处于 runnalbe 状态,但其时间切片 time slice 到期了,也会触发上下文切换以切换执行其他任务;
  • 在 UNIX/LINUX 操作系统下,操作系统执行的任务,包括线程 thread, 进程 process,这些任务的切换执行,都会涉及到 cpu context switch;
  • 进程是资源分配的基本单元,同一个进程内部可以有一个或多个线程,这些线程共享该进程的虚拟内存和全局变量(virtual memoryand and global variables);
  • 线程是 CPU 调度的基本单元,(也被称为轻量级进程),操作系统内核实际调度的对象是线程,多个线程除了共享其对应的进程中的虚拟内存和全局变量外,每个线程都还有自己的私有数据,比如栈和寄存器(stacks and registers);
  • 因为进程的上下文状态数据比线程的上下文状态数据多,所以进程切换涉及的 CPU 上下文切换开销,比线程切换涉及的 CPU 上下文切换开销要大;(所以大部分情况下,我们倾向于多线程而不是多进程);

3.2 中断处理触发的上下文切换 Interrupt handling

  • 现代的操作系统都是中断驱动的架构:比如 CPU 从磁盘读取数据的场景中,当 CPU 向 IO 设备发出读取指令后,CPU 不需要一直等待读取操作的结束, 而是可以继续执行其他的任务;当磁盘数据读取操作结束时,IO 设备可以发送中断信号以中断 CPU 当前正在执行的其它任务并将从磁盘读取的数据提供给CPU;
  • 中断处理的具体机制,涉及到以下概念:中断请求 IRQ(interrupt requests),中断服务程序 ISR (Interrupt Service Routines),以及可编程中断控制器 PIC (programmable interrupt controller等;
  • 发生中断时,需要将正在处理的任务的 CPU 上下文的一部分状态信息进行切换,这部分状态信息至少需要包含足够的信息以便 ISR 在处理完中断后可以返回到被中断的任务将要执行的下一条指令;
  • 中断处理触发的上下文切换,由于涉及的状态信息不多而且有 IO 设备等的支持,相对于多任务处理触发的上下文切换,成本要小很多;

3.3 用户态和内核态切换触发的上下文切换 User and kernel mode switching/privileged mode switch/system call switch

  • Linux 将进程执行时的状态划分内核态和用户态(kernel mode and user mode),在内核态可以访问内核空间 (kernel space),在用户态只能访问用户空间(user space);
  • 进程的内核态和用户态,是根据特权等级 privilege level 进行划分的,内核空间对应 privilege level Ring 0, 用户空间对应 privilege level Ring 3;
  • 内核空间 (Ring 0) 具有最高的权限可直接访问所有资源,用户空间 (Ring 3) 只能访问有限的资源,不能直接访问硬件资源比如内存;
  • 进程访问用户态下不能直接访问的硬件资源时,必须通过系统调用 system call 从用户态切换到内核态,比如读取某文件数据时,需要调用 open/read/write/close 等系统调用;
  • 发生系统调用时,会触发两次 CPU 上下文切换:
    • 系统调用时,首先需要保存当前 CPU 寄存器中用户态指令的地址,然后才可以将内核态指令的地址加载到 CPU 寄存器中以执行内核态的任务;
    • 系统调用结束后,需要恢复先前保存的用户态指定的地址到 CPU 寄存器中,然后才可以继续以用户态模式运行;
  • 系统调用触发的 CPU 上下文切换,也经常被称为 “特权模式切换”(privileged mode switch),与多任务 multitasking 进程切换触发的 CPU 上下文切换,有很多不同点:
    • 系统调用触发的 CPU 上下文切换,切换前后执行的是用一个进程,而多任务 multitasking 进程切换触发的 CPU 上下文切换,切换前后执行的是不同的进程;
    • 多任务 multitasking 进程切换触发的 CPU 上下文切换,涉及到用户空间的资源包括虚拟内存,栈和全局变量 (virtual memory, stacks and global variables),也涉及到内核空间的资源,比如内核栈和寄存器 (kernel stacks and registers),其状态数据比系统调用涉及的状态数据要大很多;
    • 系统统调用触发的 CPU 上下文切换,相对于多任务处理触发的 CPU 上下文切换,因为其状态数据更小,其成本也要小很多。

分类:

后端

标签:

后端

作者介绍

IT明哥
V1