多处理机
多处理机(Multiprocessor)是指在一个计算机系统中包含多个 处理器 或 处理核心,这些处理单元可以同时执行指令,从而提高系统的计算能力和并行处理能力。
多处理机的核心目的,是利用多个处理单元同时工作,提升系统的 吞吐量 和 并行计算能力。但程序能否获得明显的性能提升,还取决于任务是否可以被拆分并行执行,以及处理器之间通信、同步所产生的额外开销。
弗林分类法
弗林分类法(Flynn’s Taxonomy)是一种计算机体系结构的分类方法,由 弗林(Michael J. Flynn)于 1966 年提出。它根据计算机中 指令流 和 数据流 的数量,将计算机体系结构分为 SISD、SIMD、MIMD、MISD 四类:
| 单一指令流 | 多指令流 | |
|---|---|---|
| 单一数据流 | 单指令流单数据流(SISD) | 多指令流单数据流(MISD) |
| 多数据流 | 单指令流多数据流(SIMD) | 多指令流多数据流(MIMD) |
指令流和数据流
一条 指令 描述计算机要执行的操作,例如加法、乘法、数据传送和条件跳转等。指令中通常还会指出操作对象,例如:
ADD R1, R2
该指令表示对寄存器 R1 和 R2 中的数据执行加法。因此,指令规定执行什么操作,数据则是该操作所作用的对象。
指令流 是处理器按照一定顺序执行的一系列指令。一个独立执行程序、具有自己程序计数器的处理单元,通常对应一条相对独立的指令流。
数据流 是指令执行过程中被读取、处理和写回的一组数据。不同处理单元即使执行相同的指令,只要处理的是不同数据,也可以认为存在多条数据流。
SISD
SISD (Single Instruction Single Data) 指的是单指令流单数据流,每个指令部件每次仅译码一条指令,而且在执行时仅为操作部件提供一份数据。
如上图所示,一个 处理单元(PU,Processing Unit)接收单条 指令流,执行每条指令时,对单独的 数据 进行操作。
以 2×2 矩阵加法为例,SISD 只有一个 处理单元,每次仅读入一对元素并完成一次加法,因此需要按时间顺序串行执行 4 次运算才能得到完整结果:
SIMD
SIMD(Single Instruction Multiple Data,单指令流多数据流)是一种通过 一条指令同时处理多个数据 来实现 数据级并行性 的计算机体系结构。
如上图所示,SIMD 架构包含多个 处理单元。在同一个时刻,这些 处理单元 执行完全相同的指令,但分别处理不同的数据,因此能够并行完成大量重复计算。
这种方式能够显著提高数据密集型任务的执行效率。例如,对于一个 N × N 的矩阵加法,共需要完成 N² 次元素相加:
- 在只有 1 个处理单元的情况下,需要顺序执行 N² 次加法。
- 如果 SIMD 架构拥有 N 个处理单元,则每次指令可以同时完成 N 个元素的加法,因此只需执行 N 次即可完成整个矩阵加法。
需要注意的是,SIMD 并不是将不同的运算并行执行,而是让多个 处理单元 对不同的数据执行同一条指令,因此特别适合矩阵运算、向量运算、图像处理和科学计算等具有大量重复操作的场景。
SIMT除了 SIMD 之外,还有一个 SIMT,大家需要有所区分。
简单来说,SIMD 就是堆硬件,我多添加几个 处理单元,这样就可以同时对多个 数据 进行操作,进而实现 数据并行性。
但是这里也有一个限制,就是不同的 处理单元 在同一个时刻必须执行相同的指令。
SIMT(Single Instruction Multiple Thread)是一种并行处理形式,其中单个指令同时在多个 线程 上执行,SIMT 是 GPU 的架构方式。
与 SIMD 不同,SIMT 允许 warp 内的 线程 在一定程度上偏离相同的执行路径,也就是说不同的 线程 在同一时刻不必执行相同的指令。
MISD
MISD(Multiple Instruction Single Data)指的是多指令流单数据流,即多个 处理单元 同时对同一份 数据 执行不同的指令。
这种架构在实际应用中非常罕见,因为它难以实现,并且适用场景有限。
一些 容错系统 可能采用 MISD 架构,通过多个不同的 处理单元 对同一份 数据 进行计算,然后比较结果以确保正确性。
MIMD
MIMD(Multiple Instruction Multiple Data)指的是多指令流多数据流,多个 处理单元 同时对不同的 数据 执行不同的指令。
现代计算机中的 多核处理器 就是 MIMD 架构的典型代表。
如上图所示,与 SIMD 不同,MIMD 中的不同 处理单元 可以去处理不同的 指令流。
多核处理器
多核处理器(Multi-Core Processor)是指在一个 CPU 芯片或处理器封装中,集成两个或多个 物理核心 的处理器。
传统的单核处理器只有一个物理核心,同一时刻主要依靠指令流水线、超标量执行等机制提高单个核心的执行效率。多核处理器则通过增加物理核心的数量,使多个核心能够同时执行不同的指令流,从而提高处理器的并行处理能力。
需要区分 并发 和 并行:
- 并发 是多个任务在一段时间内交替推进,即使只有一个物理核心也可以通过快速切换实现;
- 并行 是多个任务在同一时刻真正同时执行,通常需要多个物理核心或其他并行执行单元。
因此,多核处理器的核心意义在于:
通过集成多个物理核心,使处理器能够同时执行多个指令流,从而提高多任务处理能力和多线程程序的整体吞吐量。
下面分别介绍多核处理器中的 物理核心 和 逻辑核心。
物理核心
物理核心 是 CPU 芯片上实际存在的、能够独立取指并执行指令的硬件处理单元。
每个物理核心通常包含较为完整的处理资源,例如:
- 指令获取、译码和调度部件;
- 整数、浮点和向量执行单元;
- 寄存器和流水线;
- 一级缓存等私有缓存。
部分较高级的缓存可能由多个物理核心共享,因此不能简单认为每个物理核心都拥有一套完全独立的缓存。
不同物理核心拥有各自相对完整的执行资源,可以分别运行不同的程序或线程。因此,增加物理核心通常能够直接提高 CPU 的并行处理能力。
逻辑核心
逻辑核心 是操作系统能够独立识别,并可以向其调度线程的 硬件执行上下文。
在不支持超线程的处理器中,一个物理核心通常只对应一个逻辑核心;在支持 同时多线程(SMT,Simultaneous Multithreading)的处理器中,一个物理核心可以对应多个逻辑核心。Intel 将自己的 SMT 技术称为 超线程(Hyper-Threading)。
例如,一个拥有 4 个物理核心、每个物理核心支持 2 路超线程的 CPU,会向操作系统呈现为 8 个逻辑核心。操作系统可以将不同的软件线程分别调度到这些逻辑核心上运行。
需要注意的是,逻辑核心本身并不负责调度线程。真正执行线程调度的是操作系统的调度器,逻辑核心只是调度器可以选择的硬件运行目标。
为了让一个物理核心同时维护多个逻辑核心,处理器必须为每个逻辑核心分别保存一套线程执行状态,例如:
- 程序计数器;
- 通用寄存器、标志寄存器等体系结构状态;
- 中断和异常状态;
- 部分取指、寄存器重命名和调度状态。
因此,逻辑核心并不是单纯由操作系统虚拟出来的概念,而是具有真实硬件支持的 硬件线程。
但是,超线程不会为每个逻辑核心复制一个完整的物理核心。同一物理核心中的多个逻辑核心通常还需要共享或竞争:
- 指令译码和调度资源;
- 整数、浮点和向量执行单元;
- Load/Store 单元;
- 物理寄存器文件等底层资源;
- 缓存和访存带宽。
因此,超线程可以概括为:
复制必要的线程状态,共享主要的执行资源。
逻辑核心、软件线程和物理核心之间的关系可以表示为:
当一个线程因为缓存未命中、分支预测失败等原因暂时无法充分使用执行资源时,另一个线程可以利用这些空闲资源,从而提高物理核心的利用率和整体吞吐量。
因此,一个物理核心可以对应多个逻辑核心,但逻辑核心并不等同于完整的物理核心。它增加的是可以同时维护的硬件线程数量,而不是成倍增加 CPU 的实际执行资源。
共享内存多处理机
共享内存多处理机(Shared Memory Multiprocessor)是一种并行计算机体系结构,其中多个处理器共享同一个 物理内存空间。这种架构允许处理器之间通过读写 共享内存 来进行通信和数据交换,从而实现并行计算。
共享内存多处理机 有两大主要架构特点:
- 共享内存空间 :
- 所有处理器都可以访问同一个 物理内存空间,使得数据共享变得简单高效。
- 处理器之间通过读写 共享内存 中的数据来进行通信和同步。
- 处理器互连 :
- 处理器通过互连网络(如总线、交叉开关等)连接到 共享内存。
- 互连网络的性能对 共享内存多处理机 的整体性能有重要影响。