Linux性能优化——CPU上下文切换
通过阅读文本你将了解到以下内容:
- CPU上下文切换的原理
- CPU上下文切换的种类
- CPU上下文切换对性能的影响
1. 原理
Linux是一个支持多任务的操作系统,它能够让大于CPU核心数的任务同时运行。当然,这里所说的同时有时候并不是真正意义上的同时,而是系统在很短时间内,将CPU时间片轮流分配给任务,让他们看起来像是同时运行。
系统在调度每一个任务运行时,都要知道该任务从哪里加载,从哪里开始运行,这就涉及到系统为这些任务设置CPU寄存器和程序计数器(Program Counter,PC)。这两者是CPU在运行任何任务前,必须依赖的环境,因此被称为CPU上下文。系统在切换任务时需要先保存前一个任务的CPU上下文,然后加载(或恢复)下一个任务的CPU上下文,最后跳转到PC所指位置运行任务。这一过程被称为CPU上下文切换。CPU上下文切换,是保证Linux系统正常工作的核心功能之一。
这里提到的任务到底指的是什么呢?其实任务具体分为三种:进程、线程和中断。根据任务的不同,CPU上下文切换也分为三种,即进程上下文切换、线程上下文切换和中断上下文切换。
2. 进程上下文切换
按照特权等级,进程的运行空间可分为内核空间和用户空间。进程运行在内核空间,被称为进程的内核态,此时具有最高权限,可以直接访问所有资源;进程运行在用户空间,被称为进程的用户态,此时只能访问受限资源,要想访问特权资源必须陷入到内核中。从用户态到内核态的转变,需要通过系统调用来完成。系统调用就涉及到用户态和内核态的上下文切换,这种切换一般称为特权模式切换。
进程间切换只能发生在内核态,所以进程的上下文切换不仅包含进程的用户空间资源(虚拟内存、栈、全局变量等),还包含内核空间状态(内核堆栈、寄存器等)。
什么会导致进程上下文切换呢?有以下几种情况:
- 某进程的CPU时间片耗尽,被系统挂起,切换到另一个进程。
- 由于系统资源不足,某进程再等待资源时被挂起,由系统调度其他进程。
- 进程调用sleep睡眠函数将自己挂起。
- 高优先级进程抢占低优先级进程,低优先级进程被挂起。
- 发生中断时,当前进程被挂起,转而执行中断服务程序
3. 线程上下文切换
线程与进程的最大区别在于,线程是系统调度的基本单位(执行进程的最小单元),进程是资源拥有的基本单位。内核中的任务调度实际上针对的是线程,而进程为线程提高了虚拟内存、全局变量等资源。由于线程与进程之间的这种关系,线程上下文切换分为两种情况:
- 同进程中的线程切换。有些资源是共享的,切换时保持不变,只需要切换线程的私有数据、寄存器等不共享的数据。
- 多进程中的线程切换。资源不共享,切换过程同进程上下文切换一样
4. 中断上下文切换
中断会打断进程的正常调度和执行,但中断上下文切换只发生在内核态,不涉及进程的用户态,所以中断打断一个进程时,不需要保存和恢复进程的虚拟内存、全局变量等用户态资源,只涉及到进程的内核状态和中断服务程序执行所需要的状态(CPU寄存器、内核堆栈、中断参数等)。
5. 性能影响
CPU上下文切换本身是消耗CPU的,一次上下文切换需要几十纳秒到几微秒。过多的切换会把CPU时间消耗在上下文保存与恢复上,从而会缩短任务的真正运行时间,导致系统的整体性能下降。
另外,Linux通过TLB(Translation Lookaside Buffer)来管理虚拟内存到物理内存的映射关系。当虚拟内存更新后,TLB也需要刷新,内存的访问也会随之变慢。特别是在多处理器系统上,缓存是被多个处理器共享的,刷新缓存不仅会影响当前处理器的进程,还会影响共享缓存的其他处理器的进程。
版权声明:本文为博主原创文章,转载请注明链接 https://blog.csdn.net/luroujuan/article/details/88621968