操作系统 多处理器调度
多处理器调度 或多处理器调度专注于设计系统的调度功能,其中包括多个处理器。多处理器调度中,多个CPU共享负载(负载共享),以便各个进程同时运行。通常情况下,与单处理器调度相比,多处理器调度较为复杂。在多处理器调度中,有多个处理器,它们是相同的,并且可以随时运行任何进程。
系统中的多个CPU之间进行密切的通信,共享一个公共总线、内存和其他外围设备。因此,我们可以说这个系统是紧密耦合的。这些系统用于处理大量数据,主要用于卫星、天气预报等领域。
在多处理器调度中,处理器是同质的,即功能相同。我们可以使用任何可用的处理器来运行队列中的任何进程。
多处理器系统可以是 异构 (不同类型的CPU)或 同构 (相同的CPU)。可能存在特殊的调度约束,比如通过专用总线连接到只有一个CPU的设备。
对于单处理器系统,并不存在可以被宣称为最佳调度解决方案的策略或规则。同样,对于多处理器系统,也不存在最佳调度解决方案。
多处理器调度的方法
操作系统中的多处理器调度有两种方法:对称多处理和非对称多处理。
- 对称多处理: 在每个处理器都是自己调度的情况下使用。所有进程可以在一个共享的就绪队列中,或者每个处理器可以有自己的就绪进程私有队列。调度进一步进行,通过让每个处理器的调度程序检查就绪队列并选择一个要执行的进程来进行。
- 非对称多处理: 当所有的调度决策和I/O处理都由一个称为主服务器的单个处理器处理时使用。其他处理器只执行用户代码。这种设计简单并减少了对数据共享的需求,整个场景被称为非对称多处理。
处理器亲和性
处理器亲和性意味着一个进程对当前运行的处理器有亲和力。当一个进程在特定的处理器上运行时,对缓存内存会有一定的影响。进程最近访问的数据将填充处理器的缓存。因此,进程对内存的连续访问通常会在缓存中得到满足。
现在,假设进程迁移到另一个处理器。在这种情况下,缓存内存的内容必须被第一个处理器无效化,第二个处理器的缓存必须重新填充。由于无效化和重新填充缓存的高成本,大多数对称多处理系统尝试避免将进程从一个处理器迁移到另一个处理器,并使一个进程在同一处理器上运行。这被称为处理器亲和性。处理器亲和性有两种类型,如下:
- 软亲和性: 当操作系统具有在同一处理器上保持进程运行的策略,但不能保证一定会这样做时,这种情况被称为软亲和性。
- 强亲和性: 强亲和性允许进程指定其可以运行的处理器子集。一些Linux系统实现了软亲和性,并提供了支持强亲和性的系统调用,如 sched_setaffinity() 。
负载均衡
负载均衡是在SMP系统中将工作负载均匀分配到所有处理器上的现象。只有在每个处理器都有自己的私有进程队列且这些进程有资格执行的系统上才需要负载均衡。
不需要负载均衡,因为一旦处理器空闲,它就会立即从通用运行队列中提取可运行进程。在SMP(对称多处理)系统上,需要保持所有处理器的工作负载平衡,以充分利用拥有多个处理器的好处。其中一个或多个处理器将处于空闲状态,而其他处理器具有高工作负载以及等待CPU的处理器列表。负载均衡有两种一般方法:
- 推动迁移: 在推动迁移中,一个任务会定期检查每个处理器的负载情况。如果发现不平衡,它会通过将进程从过载的处理器移动到空闲或较不繁忙的处理器上,使负载均匀分布在每个处理器上。
- 拉动迁移: 当一个空闲的处理器从忙碌的处理器中接收等待的任务并执行时,就发生了拉动迁移。
多核处理器
在多核处理器中,多个处理器核心被放置在同一物理芯片上。每个核心都有一个寄存器集来维护其架构状态,因此在操作系统看来,它们是独立的物理处理器。
使用多核处理器的SMP系统 比每个处理器都有自己的独立物理芯片的系统更快且消耗更少的电力。
然而,多核处理器可能会使调度问题复杂化。当处理器访问内存时,它会花费大量时间等待数据可用。这种情况被称为 内存停顿 。它发生的原因有多种,例如缓存未命中,即访问不在缓存内存中的数据。
在这种情况下,处理器可能会花费高达50%的时间等待内存中的数据变得可用。为了解决这个问题,最新的硬件设计实现了多线程处理器核心,每个核心分配了两个或更多的硬件线程。因此,如果一个线程在等待内存时停顿,核心可以切换到另一个线程。有两种方式可以多线程处理器:
- 粗粒度多线程: 在粗粒度多线程中,线程在处理器上执行,直到发生长延迟事件,例如内存停顿。由于长延迟事件引起的延迟,处理器必须切换到另一个线程开始执行。线程之间的切换成本很高,因为在其他线程可以在处理器核心上开始执行之前,指令流水线必须被终止。一旦新线程开始执行,它就开始用其指令填充流水线。
- 细粒度多线程: 细粒度多线程在更细的级别上切换线程,主要在指令周期的边界处切换。细粒度系统的体系结构设计包括线程切换的逻辑,因此线程之间的切换成本很小。
对称多处理器
对称多处理器(SMP)是第三个模型。在此模型中,内存中有一个操作系统的副本,但任何中央处理单元都可以运行它。现在,当进行系统调用时,进行系统调用的中央处理单元会捕获内核并处理该系统调用。该模型动态平衡进程和内存。该方法使用对称多处理,其中每个处理器都是自调度的。
调度继续进行,通过使每个处理器的调度器检查准备队列并选择要执行的进程。在此系统中,所有进程都可能在一个共同的准备队列中,或者每个处理器都可能有其私有队列来保存准备好的进程。在多处理器操作系统中,主要有三个争用来源。
- 锁系统: 由于多处理器系统中共享资源,有必要保护这些资源,以便多个处理器可以安全访问。锁定方案的主要目的是使多个处理器按顺序访问资源。
- 共享数据: 当多个处理器同时访问相同的数据时,可能会导致数据不一致,为了保护数据一致性,必须使用一些协议或锁定方案。
- 缓存一致性: 它是存储在多个本地缓存中的共享资源数据。假设两个客户端都有一个内存的缓存副本,其中一个客户端更改了内存块。另一个客户端可能会没有收到更改的通知而留下一个无效的缓存,因此通过维护数据的一致视图来解决此冲突。
主从多处理器
在这种多处理器模型中,有一个单一的数据结构来跟踪准备好的进程。在这个模型中,一个中央处理单元充当主机,另一个充当从机。所有处理器都由一个称为主服务器的单个处理器处理。
主服务器运行操作系统进程,从服务器运行用户进程。内存和输入输出设备在所有处理器之间共享,并且所有处理器连接到一个公共总线。这个系统简单且减少数据共享,因此这个系统被称为 非对称多处理 。
虚拟化和线程
在这种类型的 多处理器 调度中,即使是单个CPU系统也可以像多处理器系统一样工作。在具有虚拟化的系统中,虚拟化为系统上运行的每个虚拟机呈现一个或多个虚拟CPU。然后,它在虚拟机之间调度物理CPU的使用。
- 大多数虚拟化环境都有一个主机操作系统和许多客户操作系统,主机操作系统创建和管理虚拟机。
- 每个虚拟机都安装了一个客户操作系统,应用程序在其中运行。
- 每个客户操作系统可以分配用于特定用例、应用程序或用户的操作系统,包括时间共享或实时操作。
- 任何假设在给定时间内有一定进展的客户操作系统调度算法都会受到虚拟化的负面影响。
- 时间共享操作系统尝试将每个时间片分配给100毫秒,以给用户合理的响应时间。给定的100毫秒时间片可能需要超过100毫秒的虚拟CPU时间。根据系统的繁忙程度,时间片可能需要一秒钟或更长时间,这导致用户登录到该虚拟机的响应时间非常差。
- 这种调度层叠的净效果是,尽管虚拟化操作系统认为它们正在接收所有周期并调度所有这些周期,但它们只接收了一部分可用CPU周期。虚拟机中的时钟通常是不准确的,因为计时器触发所需时间与专用CPU上的时间相同。
- 虚拟化可能会撤销虚拟机内操作系统的良好调度算法工作。