硬件多线程的基本概念
上一节的 SIMD 是”复制运算部件、共享控制器”。这一节讲的硬件多线程恰好是它的镜像:复制线程状态、共享运算部件。
出发点是一个很实际的观察:流水线经常在空转。 一次 Cache 未命中要等几十上百拍(3.5.2),这段时间里所有功能部件全都闲着——而闲着的原因只是”这一个线程卡住了”。
如果 CPU 里还存着另一个线程的完整状态,它就可以立刻切过去干活。 这就是硬件多线程的全部思想。
机制
要复制什么、共享什么
这是本节的钥匙,和 5.7.1 用的是同一条判据。
| 复制(每个线程一套) | 共享(所有线程共用) | |
|---|---|---|
| 硬件多线程 | PC、通用寄存器组、PSW、页表基址寄存器 | ALU、译码器、Cache、TLB、分支预测器 |
复制的那一组,正好就是 5.1.3 说的 ISA 状态——PC、通用寄存器、PSW。这不是巧合:一个线程的全部身份就是它的 ISA 状态,把这组东西复制一份,硬件就同时”记得”两个线程。
由此得到硬件多线程最重要的性质:
线程切换不需要保存和恢复现场——因为两套状态本来就同时存在。
对比操作系统的进程切换(OS 2.2.4):那里要把寄存器一个个存进 PCB、再从另一个 PCB 一个个读出来,开销是几百到几千个时钟周期。而硬件多线程的切换只需要改一个”当前用哪套寄存器”的选择信号,开销可以低到 0 个周期。
这个对比是理解硬件多线程价值的关键:它把”切换”这件事从软件的百拍级别降到了硬件的零拍级别,于是”卡一下就切走”才变得划算。
三种硬件多线程
判据只有一条:同一个时钟周期里,能不能有多个线程的指令同时在执行。
| 细粒度多线程 | 粗粒度多线程 | 同时多线程 SMT | |
|---|---|---|---|
| 切换时机 | 每个时钟周期都轮换 | 只在长阻塞时(如 Cache 缺失) | 不切换 |
| 同一拍有几个线程的指令 | 1 个 | 1 个 | 多个 |
| 能隐藏什么 | 短停顿也能隐藏 | 只能隐藏长阻塞 | 两者都能 |
| 切换开销 | 0(硬件轮转) | 大——要排空流水线 | —— |
| 需要超标量吗 | 否 | 否 | 必须 |
| 单线程性能 | 下降(被别的线程分走周期) | 基本不变 | 基本不变 |
三者的关系是一条递进:
- 粗粒度:只在实在跑不动的时候才换人。切换要排空流水线(流水线里还有本线程的指令),所以只有停顿足够长时才划算。
- 细粒度:每拍换一个人。不需要排空——因为流水线各段本来就装着不同线程的指令。代价是单个线程被拖慢了(它每
拍才轮到一次)。 - SMT:不换人,让多个人同时上。 前提是有超标量的多发射能力(5.6.5)——一拍能发 4 条指令,那这 4 条来自 2 个线程也无妨。
SMT 为什么必须以超标量为基础:如果每拍只能发射一条指令,那”同时”就无从谈起——同时多线程的”同时”,指的正是同一拍的多个发射槽被不同线程占用。
而 SMT 的收益来源也正在这里:超标量的发射槽经常填不满(5.6.5 说的 ILP 不够),一个线程填不满,两个线程就容易填满。
只有线程 A: [A1][A2][--][--] ← 4 个发射槽只用了 2 个
A + B 同时: [A1][A2][B1][B2] ← 填满了
超线程:Intel 对 SMT 的商标名
超线程(Hyper-Threading)= Intel 的 SMT 实现,通常是每个物理核心提供 2 个逻辑核心。
| 物理核心 | 逻辑核心 | |
|---|---|---|
| 有几套 ALU | 1 套 | 共享那 1 套 |
| 有几套寄存器/PC | 1 套 | 各有一套 |
| 操作系统看到 | —— | 当成独立 CPU 来调度 |
关键点:逻辑核心不是真正的核心。 两个逻辑核心共用一套运算部件,所以两个线程一起跑,绝不会有两倍的性能——典型提升在 15%~30%,而且高度依赖负载。
疑问点:在 macOS 上怎么看物理核心数和逻辑核心数
sysctl -n hw.physicalcpu hw.logicalcpu两个数字的关系直接给出答案:
结果 说明 逻辑 = 物理 没有硬件多线程 逻辑 = 物理 × 2 有 SMT / 超线程,每核 2 线程 逻辑 = 物理 × 4 每核 4 线程(部分 IBM POWER、部分服务器芯片) 补充几个常用的:
sysctl -n hw.ncpu machdep.cpu.brand_stringLinux 上对应的是
lscpu,看Thread(s) per core这一行。
疑问点:物理核心 10、逻辑核心 10,说明这台 Mac 的芯片没有硬件多线程吗
是的,这个推断完全正确——而且 Apple Silicon 确实不实现 SMT。
判据就是那个等式:逻辑 = 物理 ⟹ 每个物理核心只提供一个线程 ⟹ 没有 SMT。
不做 SMT 是一个设计选择,理由有三条:
理由 说明 收益变小 SMT 的收益来自”填补空闲发射槽”。核心本身的乱序窗口越大、Cache 越大、分支预测越准,空槽就越少——ARM 大核走的正是”宽而深”路线,空槽本来就不多 面积和功耗 复制一整套寄存器和线程状态要占面积;同样的晶体管拿去做更大的 Cache 或多加一个真核心,收益可能更高 安全 共享执行部件带来侧信道攻击面(同一物理核上的两个线程能互相观测执行时序),近年有若干公开漏洞与此相关 而与之相反的取舍是:服务器负载往往是大量互相独立的请求,线程多、每个线程的 ILP 都不高——这正是 SMT 最能发挥的场景。所以 x86 服务器芯片普遍保留超线程,而面向单线程响应速度的设计倾向于不做。
一句话:SMT 不是”更先进”,它是一个在特定负载下划算的取舍。
疑问点:判断这句话——"超线程是一项硬件技术,能使系统性能大幅提升,与操作系统和应用软件无关"
错,而且错在两处,每一处都能单独让这句话不成立。
错误一:“大幅提升”言过其实。
超线程只是让两个线程共享同一套运算部件,运算能力一点没增加。它的收益来自填补原本空闲的发射槽,典型幅度 15%~30%。
而且并非总是正收益:
负载类型 超线程的效果 多个互相独立、各自 ILP 不高的线程 收益最大(服务器负载) 单线程重计算 无收益(另一个逻辑核没事干) 两个线程都密集使用同一类部件(如都在做浮点) 可能变慢——抢同一个 FPU 两个线程的工作集加起来超过 L1/L2 可能变慢——互相冲刷对方的 Cache 最后一行值得单独记:两个逻辑核共享 Cache(3.5.3),工作集一大就互相踢出对方的数据,Cache 命中率下降的损失可能超过填槽的收益。
错误二:“与操作系统和应用软件无关”——这一处更严重。
超线程必须由操作系统支持才能正确发挥作用,理由是调度:
假设一台 4 物理核 / 8 逻辑核的机器,现在要跑 4 个线程。
调度方式 结果 OS 不区分逻辑核与物理核 可能把 4 个线程放到 2 个物理核的 4 个逻辑核上 → 另外 2 个物理核完全闲置,性能几乎腰斩 OS 知道拓扑 优先把线程分散到不同物理核 → 4 个物理核各跑 1 个,满速 所以操作系统必须知道”哪两个逻辑核属于同一个物理核”,这个信息叫 CPU 拓扑,由固件(ACPI/CPUID)报告给内核。调度器据此优先跨物理核分配——这正是 OS 2.2.6 多处理机调度要处理的问题之一,也和处理器亲和性直接相关。
应用软件同样有关:只有多线程的程序才能用上第二个逻辑核。单线程程序开不开超线程完全一样。
顺带说,这道题的出题点其实是”与操作系统无关”这半句——它是所有”硬件技术自动生效”类说法的通病。判据:凡是需要操作系统调度配合的硬件特性,都不可能”与操作系统无关”。 同类说法还有 NUMA(5.7.4)、大小核调度。
硬件多线程与 SIMD、多核的三方对照
把 5.7 前三节的判据并排放一次:
| 复制了什么 | 共享了什么 | 并行层次 | |
|---|---|---|---|
| SIMD | 运算部件(ALU) | 控制器(取指译码) | 数据级 DLP |
| 硬件多线程 | 线程状态(PC、寄存器) | 运算部件、Cache | 线程级 TLP |
| 多核 | 控制器 + 运算部件(整个核) | 末级 Cache、内存 | 线程级 TLP |
SIMD 和硬件多线程正好是镜像的一对:一个复制干活的、共享指挥的;另一个复制指挥的、共享干活的。多核是两者都复制。
这张三行表就是 5.7 全节的骨架,也是 5.1.1 那条”并行度三层次”主线的最终形态。
边界
层次辨析:三种硬件多线程
判据:同一拍能不能有多个线程的指令。
- 细粒度:每拍换线程,同一拍只有 1 个线程
- 粗粒度:只在长阻塞时换,同一拍只有 1 个线程
- SMT(超线程):同一拍可以有多个线程的指令
只有 SMT 需要超标量作基础。
边界辨析:逻辑核心 / 物理核心
- 物理核心:有自己完整的一套运算部件
- 逻辑核心:只有自己的一套寄存器和 PC,运算部件是共享的
个逻辑核心的性能远小于 个物理核心。检查方法: hw.logicalcpu是否等于hw.physicalcpu。
边界辨析:硬件线程切换 / 操作系统线程切换
- 硬件多线程的切换:两套寄存器同时存在,不需要保存恢复,开销可低至 0 拍
- OS 的线程/进程切换(OS 2.2.4):要存进 PCB 再读出来,开销几百到几千拍
正因为硬件切换几乎免费,“卡一下就切走”才划算。
边界辨析:超线程 ≠ 双核
- 超线程:1 个物理核心,模拟出 2 个逻辑核心,运算部件共享
- 双核:2 个完整的物理核心,运算部件各有一套
这是选择题的经典干扰项,见 5.7.3。
对照速查
| 切换时机 | 同拍多线程 | 需超标量 | 单线程性能 | |
|---|---|---|---|---|
| 细粒度 | 每拍 | ❌ | ❌ | 下降 |
| 粗粒度 | 长阻塞 | ❌ | ❌ | 基本不变 |
| SMT | 不切换 | ✅ | ✅ | 基本不变 |
| 说法 | 判断 |
|---|---|
| 硬件多线程需要为每个线程复制寄存器组和 PC | ✅ |
| 硬件多线程各线程共享功能部件和 Cache | ✅ |
| 同时多线程可以在同一周期发射多个线程的指令 | ✅ |
| 细粒度多线程能隐藏短停顿 | ✅ |
| 粗粒度多线程切换开销小 | ❌ 要排空流水线 |
| 超线程使性能翻倍 | ❌ 典型 15%~30% |
| 超线程与操作系统无关 | ❌ 必须 OS 知道拓扑 |
| 逻辑核心数一定等于物理核心数 | ❌ 有 SMT 时是倍数 |
考点
- 三种硬件多线程的辨析:判据是”同一拍有几个线程的指令”。只有 SMT 是多个。
- 硬件多线程复制什么:PC、寄存器组、PSW(= ISA 状态);共享 ALU、Cache。
- SMT 为什么要以超标量为基础:没有多发射就无所谓”同时”。
- 超线程相关判断题:“大幅提升”错、“与 OS 无关”错、“等于双核”错。
- 逻辑核心与物理核心的关系:逻辑 = 物理 × 每核线程数。
链接
- 🏠 返回总览:计算机组成原理第 5 章:中央处理器总览
- ⬅️ 上一节:5.7.1 SISD、SIMD、MIMD 的基本概念
- ➡️ 下一节:5.7.3 多核处理器的基本概念
- 🔗 超标量是 SMT 的前提:5.6.5 高级流水线技术
- 🔗 OS 对照:OS 2.2.6 多处理机调度
- 🔗 OS 对照:OS 2.2.4 进程切换
- 📖 名词库:第 5 章名词库