芯片多处理器中的核心多线程技术解析
1. 单线程 5 级流水线的执行情况
在单线程的 5 级流水线中,核心会在计算和 L1 缺失之间交替进行,每段时间间隔为 20 个时钟周期。直到出现 L2 缺失时,核心会暂停 200 个时钟周期。例如,执行 200 条指令的总时间为 10 × 40 + 200 = 600 个周期,CPI(每条指令的时钟周期数)为 600 / 200 = 3,是无缓存缺失时 CPI 的三倍。这表明在等待内存时,核心吞吐量的三分之二被浪费了。
为了解决这个问题,现代处理器提供了硬件支持,用于在缓存缺失时进行快速上下文切换和高效的多线程处理。硬件支持应避免在每次缺失时保存/恢复机器状态,并具备从一个线程快速切换到另一个线程的机制。
2. 硬件辅助的核心多线程类型
硬件辅助的核心多线程主要有两种基本类型:块(或粗粒度)多线程和交错(或细粒度)多线程。
2.1 块(粗粒度)多线程
2.1.1 5 级流水线中的块多线程
在 5 级流水线中支持双向块多线程的改动相对较小。当发生 L1 缺失时,核心不会停顿。而是指令或数据缓存的缺失会引发一个低级硬件异常,该异常在写回阶段被处理,使用与常规 5 级流水线相同的软件异常机制。缺失的指令以及处于 IF、ID、EX 和 MEM 阶段的指令会被刷新。在周期结束时,缺失线程的程序计数器会重置为缺失指令的地址。同时,IF 阶段的线程选择器会取消选择缺失线程的 PC,并在下一个周期选择备用线程进行指令提取。总共浪费的周期数为 5 个周期。
除了支持刷新指令和选择线程外,机器的架构状态必须复制,以便核心能够立即从一个线程的状态切换到另一个线程的状态。例如,一个双向多线程核心必须有两个程序计数器、两组寄存器、两个页表基寄存器和两组条件/中断标志(均为物理的)。L1 和 L2 缓存空间由线程共享,为避免线程之间的冲突缺失,两个线程的 TLB 也可以分开。
线程选择器最初由低级硬件异常机制驱动,一个线程在遇到触发硬件异常的事件之前不会被切换。当一个线程被挂起,另一个线程遇到长延迟事件时,挂起的线程会重试执行。如果再次缺失,它会再次被挂起,直到其中一个线程成功。更复杂的线程选择器可以根据缓存的指示来决定线程是否重新执行。
2.1.2 双向块多线程 5 级流水线中缓存缺失的影响
当两个线程共享 5 级流水线核心时,线程 T1 执行 20 个周期后遇到 L1 缓存缺失,耗时 20 个周期,此时线程 T1 被挂起,线程 T2 开始运行,线程切换过程需要几个周期,标记为“切换开销”。线程 T1 和 T2 交替执行和发生 L1 缓存缺失,最初核心可以通过重叠一个线程的执行和另一个线程的 L1 缓存活动来充分利用资源。当线程 T1 遇到 200 个周期的 L2 缓存缺失时,线程 T2 开始执行,但它也可能遇到 L1 缓存缺失甚至 L2 缓存缺失,此时 CPU 会空闲,标记为“空闲时间”。为了使这个方案有效,L1 和 L2 缓存必须无锁定,并且能够同时处理两个缓存访问。
由于 L2 缺失的延迟非常长,更多的线程上下文应该共享核心以提高核心利用率。随着线程数量的增加,一些机制(如线程选择)会变得更复杂,架构资源的复制也会与线程数量成比例增加。共享资源(如缓存和 TLB)的大小也必须相应扩大,以适应越来越多线程的工作集。
2.1.3 乱序核心中的块多线程
块多线程在简单的 5 级流水线中容易实现,但主要问题是切换开销。这种开销限制了线程切换的机会,只能在相对长延迟的事件中进行。在乱序机器中,为了避免不同线程指令执行的混合,缺失异常在重排序缓冲区的顶部处理,大量指令必须被刷新,取消了大量工作,然后下一个线程必须重新填充流水线,因此切换开销很容易达到数十个周期。为了在乱序处理器中实现块多线程,除了保存架构状态的结构外,其他结构(如分支预测硬件或 TLB)也经常被复制。
2.1.4 双向乱序处理器中块多线程的执行示例
考虑两个各有六条指令的线程片段的执行。机器是具有推测调度的双向乱序机器,每个线程有自己的指令提取队列(IFQ)。指令以每个周期两条的速率提取、解码和分发,每个周期最多可以退休两条指令。公共数据总线(CDB)每个周期可以转发两个结果,最多可以从一个具有四个条目的统一发行队列中调度两条指令。假设线程 1 先执行,其调度情况如下表所示:
| Instruction (latency) | Dispatch (issue Q) | Register Issue | Exec fetch | Exec start | Exec complete | Retire (T1) | Retire (T2) |
| — | — | — | — | — | — | — | — |
| X1 (2) | 1(1) | 2 | 3 | 4 | 5 | 6 | 7 |
| X2(2) | 1(2) | 4 | 5 | 6 | 7 | 8 | 9 |
| X3(4) | 2(3) | 4 | 5 | 6 | 9 | 10 | 11 |
| X4(2) | 2(4) | 8 | 9 | 10 | 11 | 12 | 13 |
| X5(1, 20) | 9(3) | 10 | 11 | 12∗ | 12 | 13 | |
| X6(1) | 9(4) | 11 | 12 | 13 | 13 | 14 | |
| Y1(2) | 15(1) | 16 | 17 | 18 | 19 | 20 | 21 |
| Y2(3) | 15(2) | 18 | 19 | 20 | 22 | 23 | 24 |
| Y3(2) | 16(3) | 21 | 22 | 23 | 24 | 25 | 26 |
| Y4(2) | 16(4) | 23 | 24 | 25 | 26 | 27 | 28 |
| Y5(3) | 24(3) | 25 | 26 | 27 | 29 | 30 | 31 |
| Y6(1) | 24(4) | 28 | 29 | 30 | 30 | 31 | 32 |
| X5(1, 20) | 32(3) | 33 | 34 | 35 | 35 | 36 | 37 |
| X6(1) | 32(3) | 34 | 35 | 36 | 36 | 37 | 38 |
在这个示例中,总共 12 条指令在 32(34 - 2)个周期内发行,发行率为 12 / 32 = 0.375 每条时钟,CPI 约为 2.7,比单线程核心要好得多。
2.1.5 具有块多线程的处理器示例
- IBM iSeries SStar 处理器 :这是一个块多线程处理器,IBM 将此功能称为硬件多线程(HMT)。SStar 是用于运行商业工作负载的服务器处理器,是一个具有 5 级流水线的四路超标量顺序处理器。由于商业工作负载有许多线程,但会遭受大量的缓存缺失,HMT 主要在 L1 或 L2 缓存缺失时切换线程。为了最小化面积和设计复杂性,只支持两个线程:前台和后台线程。控制寄存器指定线程切换上下文的条件,如 L1 缓存缺失、L2 缓存缺失和线程切换超时。线程切换发生在前台线程遇到 L1 缓存缺失时,但如果后台线程已经在等待缓存缺失,切换会根据情况进行调整。架构状态被复制,但所有功能单元、流水线资源、缓存和 TLB 是共享的。在 L1 Dcache 缺失时,线程切换在写回阶段触发,由于后台线程的指令已经在备用指令缓冲区中缓冲和预解码,线程切换的惩罚只有 3 个周期。最小化的复制和广泛的资源共享将 HMT 的面积开销降至 5% 以下,对周期时间的影响小于 1%。
- Intel 的 Montecito 处理器 :这是一个双核处理器,每个核心有两个线程,实现了 IA - 64(Itanium 2)指令集架构。每个核心是一个顺序执行流水线,长延迟的 L3 缓存缺失会导致片外内存访问。Montecito 在每个核心中使用块多线程来在 L3 缓存缺失/数据返回、时间片到期和软件提供的线程切换提示等事件时切换线程。线程切换提示通过添加到 ISA 的特殊指令传达,这些事件会被纳入线程紧急级别。当挂起线程的紧急性高于运行线程时,会发生线程切换。寄存器文件被复制,但线程共享内存层次结构。分支预测结构也被共享,但为了防止一个线程的分支历史污染另一个线程的分支历史,线程 ID 是索引历史和预测表的位集的一部分。复制架构状态导致芯片面积增加 2%。
2.2 交错(细粒度)多线程
粗粒度多线程无法利用由单个指令操作的短延迟引起的停顿周期,因为一次只有一个线程运行。而在交错多线程中,多个线程可以同时在核心上运行。处理器在连续的周期中从不同线程提取、解码和调度指令,不同运行线程的指令执行被精细地交错,一条指令接着一条指令。如果一个线程遇到长延迟事件(如缓存缺失),它会被暂时挂起。通过在每个周期交替线程执行,即使每个线程存在数据依赖和冲突,也可以使处理器保持忙碌。
2.2.1 5 级流水线中的交错多线程
在 5 级流水线中,交错多线程的操作在有两个和五个运行线程的情况下进行了说明。运行线程在每个周期依次被选择执行,不同阶段由不同线程占用。当有两个线程时,由加载指令后跟依赖指令引起的气泡会被消除,因为同一线程的指令每隔一个周期开始。当有五个运行线程时,每个流水线阶段处理来自不同线程的指令,流水线阶段之间互不影响。
交错多线程的 5 级流水线基本架构与支持块多线程的架构类似,但有三个显著差异:
-
数据转发必须感知线程
:任何转发的值都携带 TID(线程上下文 ID),并且只有通过匹配转发值的 TID 和开始执行的指令的 TID,才能将值转发到同一线程。
-
阶段刷新必须感知线程
:当在写回阶段发生异常时,IF、ID、EX 和 MEM 阶段不能随意刷新,包含其他线程指令的阶段不会被刷新,对于分支跳转也是如此。
-
线程选择算法不同
:线程选择器在每个周期选择一个不同的线程。简单的算法是按循环方式从运行线程集合中选择下一个线程。每当一个线程遇到长延迟事件时,选择器会将其搁置并暂时将其从每个周期选择的运行线程集合中移除。一旦事件完成,线程选择器会将该线程重新插入运行线程集合。
交错多线程在 5 级流水线中的效率比块多线程更好,因为消除了流水线气泡,并且在长延迟事件和分支跳转时刷新的指令更少。当有两个线程运行时,分支跳转的惩罚是 1 个时钟,异常(硬件或软件)的惩罚是 3 个时钟;当有五个线程运行时,分支跳转的惩罚是 0 个时钟,异常的惩罚是 1 个时钟。需要注意的是,当单线程在多线程机器(包括块和交错多线程)上运行时,其运行速度与基本单线程 5 级流水线相同。
2.2.2 交错多线程的示例
Sun Sparc T1 和 T2 处理器的核心架构是交错多线程微架构的一个很好的例子。T1 和 T2 的主要目标市场是商业或客户端 - 服务器应用程序,如数据库系统、在线事务处理或基于 Web 的应用程序。在这种环境中,大量客户端向集中式服务提供商请求服务,客户端请求会触发服务器中并行、独立线程的执行。这些线程很少或没有浮点执行,主要执行整数和内存指令,并且受缓存缺失开销的影响较大。客户端 - 服务器应用程序需要高水平的线程执行吞吐量,由于其丰富的自然并行性,是多线程机器的主要目标。
Sun Sparc T1 有八个核心,每个核心运行四个线程,总共 32 个线程;Sun Sparc T2 有八个核心,每个核心有八个线程,总共 64 个线程。核心是单发射整数流水线。在 T1 和 T2 中,每个核心都有一级缓存,核心通过交叉开关共享一个分块的 L2 缓存。L1 缓存之间的一致性由每个 L2 缓存块中保存的 L1 缓存内容目录维护。
以 T1 为例,假设每个核心有两个线程,其架构仍然是一个顺序流水线,类似于 5 级流水线,但更复杂,并且避免了在长延迟事件时使用硬件异常来挂起线程。主要区别是将指令提取阶段与解码阶段解耦,两个阶段之间有两个指令提取队列(IFQ),每个线程一个,其目的是在 I - 缓存缺失时平滑指令向流水线的交付。分支使用 Sparc V9 分支指令中提供的软件预测(提示)位进行静态预测。
线程选择逻辑在每个周期选择一个线程进行提取和解码。如果两个线程都在运行并且执行低延迟指令,选择算法就是简单的循环。如果其中一个线程遇到长延迟事件,选择逻辑会暂时挂起该线程。线程选择算法还会根据指令的操作码对单个指令的延迟敏感,并相应地对其选择进行优先级排序。在分支、浮点操作或复杂整数操作(如除法或乘法)的情况下,可能会取消选择一个线程。
2.3 桶形处理器
交错多线程发展到极致会产生一种非常简单的流水线机器,称为桶形处理器。有足够的线程上下文和足够的运行线程时,即使同一线程的两条指令不同时在流水线中,也可以使核心保持忙碌,从而消除了对数据和控制冲突硬件的需求。每个线程上下文一次执行一条指令,就像在非流水线机器中一样。在有足够多线程运行的情况下,可以容忍长内存访问延迟,甚至可以使用非常大且慢的数据缓存而不会使流水线饥饿,或者完全不使用数据缓存。
一个具有 5 级流水线的桶形处理器可以通过复制 32 个线程上下文来支持 32 个线程的并发执行。然而,这种架构范式到目前为止还没有成功,原因如下:
-
线程数量需求
:以当前技术,工作负载中需要数百个线程才能使流水线保持忙碌,而这么多线程上下文所需的硬件状态是难以承受的。
-
微架构差异
:微架构与历史遗留的微架构差异太大,其他利用廉价现成微处理器的大规模并行架构在处理大量线程的工作负载时更成功。
-
单线程执行时间
:即使机器在每单位时间内执行的线程数量方面具有非常高的吞吐量,但每个线程的执行速度非常慢。除了具有无限并行性的应用程序外,多线程机器不能完全牺牲单线程执行时间来换取线程执行吞吐量。
桶形处理器的概念由来已久,例如 Control Data Corporation 在 20 世纪 60 年代为 CDC6600 设计 I/O 处理器时就开创了这个想法。后来,Denelcor 的 HEP(Heterogeneous Element Processor)在 20 世纪 80 年代初作为一个包含多达 16 个处理器元素的多处理器系统进行销售,每个处理器元素是一个 8 级流水线,至少需要八个进程才能充分利用流水线。
综上所述,块多线程和交错多线程各有优缺点,在不同的应用场景和处理器架构中发挥着不同的作用。桶形处理器虽然概念简单,但由于技术和实际应用的限制,尚未得到广泛应用。在选择多线程技术时,需要根据具体的工作负载和性能需求进行权衡。
下面是一个简单的 mermaid 流程图,展示块多线程中线程切换的基本流程:
graph TD;
A[线程执行] --> B{是否发生 L1 缺失};
B -- 是 --> C[触发硬件异常];
C --> D[刷新相关指令];
D --> E[重置缺失线程 PC];
E --> F[选择备用线程];
F --> G[备用线程执行];
B -- 否 --> A;
G --> H{备用线程是否发生长延迟事件};
H -- 是 --> I[挂起线程重试执行];
I --> J{是否再次缺失};
J -- 是 --> I;
J -- 否 --> A;
H -- 否 --> G;
通过以上对不同多线程技术的分析,我们可以更深入地理解芯片多处理器中如何利用多线程来提高性能和资源利用率。在实际应用中,开发者需要根据具体的需求和场景选择合适的多线程技术,以达到最佳的性能表现。
3. 不同多线程技术的对比总结
3.1 性能对比
| 多线程技术类型 | 切换开销 | 指令刷新情况 | 流水线气泡 | CPI 表现 | 核心利用率 |
|---|---|---|---|---|---|
| 块(粗粒度)多线程 | 较高,在简单 5 级流水线约 5 个周期,乱序核心可达数十个周期 | 较多,长延迟事件时大量指令需刷新 | 较多,存在因线程切换导致的流水线空闲 | 比单线程核心好,如示例中约为 2.7 | 受 L2 缺失影响大,需更多线程提高利用率 |
| 交错(细粒度)多线程 | 较低,根据线程数量不同,分支和异常惩罚小 | 较少,长延迟事件和分支跳转时刷新指令少 | 少,可消除部分由指令依赖引起的气泡 | 效率优于块多线程 | 较高,能更好利用短延迟停顿周期 |
| 桶形处理器 | - | 理论上无需处理复杂的指令刷新 | 无,同一线程不同时在流水线 | - | 理论上可充分利用资源,但实际受线程数量限制 |
3.2 架构特点对比
| 多线程技术类型 | 架构状态复制 | 资源共享情况 | 线程选择机制 |
|---|---|---|---|
| 块(粗粒度)多线程 | 需复制架构状态,如程序计数器、寄存器等 | 功能单元、流水线资源、缓存和 TLB 可共享 | 最初由硬件异常驱动,复杂选择器可根据缓存指示 |
| 交错(细粒度)多线程 | 复制相关架构状态 | 缓存等资源共享 | 按循环方式选择线程,考虑指令延迟和长延迟事件 |
| 桶形处理器 | 大量复制线程上下文 | 可根据情况决定是否使用缓存等资源 | 多个线程循环执行,简单交替 |
3.3 应用场景对比
| 多线程技术类型 | 适用应用场景 | 原因分析 |
|---|---|---|
| 块(粗粒度)多线程 | 商业工作负载、长延迟缓存缺失场景 | 可在长延迟事件时切换线程,如 IBM SStar 和 Intel Montecito 用于服务器处理商业任务 |
| 交错(细粒度)多线程 | 客户端 - 服务器应用,如数据库、在线事务处理 | 能利用短延迟停顿,提高线程执行吞吐量,如 Sun Sparc T1 和 T2 |
| 桶形处理器 | 理论上适用于有大量独立线程的场景 | 但实际受限于线程数量和硬件状态需求,未广泛应用 |
4. 多线程技术的优化建议
4.1 块多线程优化
- 减少切换开销 :在乱序核心中,优化指令刷新和流水线填充过程,可通过提前预测长延迟事件,减少不必要的指令刷新,或者采用更高效的流水线重新填充策略。例如,预取部分关键指令到特定缓冲区,在切换线程时快速填充流水线。
- 优化线程选择策略 :除了基于硬件异常的选择,引入更多因素,如线程的优先级、剩余执行时间等,使线程选择更加智能。可以设计一个线程优先级队列,根据线程的重要性和执行进度动态调整优先级。
4.2 交错多线程优化
- 改进线程选择算法 :不仅仅考虑循环和指令延迟,结合线程的资源占用情况、缓存命中率等因素进行综合选择。例如,优先选择缓存命中率高的线程,减少缓存缺失带来的停顿。
- 增强数据转发机制 :提高数据转发的效率和准确性,确保线程之间的数据传递更加顺畅。可以采用更复杂的 TID 匹配算法,减少数据转发的错误和延迟。
4.3 桶形处理器优化
- 探索新的硬件技术 :寻找能够支持大量线程上下文的硬件实现方式,降低硬件状态的成本。例如,研究新型的存储技术,提高线程上下文存储的密度和速度。
- 优化线程调度策略 :设计更合理的线程调度算法,在有限的线程资源下,尽量提高流水线的利用率。可以采用动态线程分配策略,根据工作负载的变化实时调整线程数量。
5. 多线程技术的未来发展趋势
5.1 集成化与智能化
未来的多线程技术将更加集成化,处理器会将不同类型的多线程技术进行融合,根据不同的工作负载自动选择最合适的模式。同时,线程选择和调度机制将更加智能化,利用机器学习等技术,根据历史数据和实时状态预测线程的行为,做出最优的决策。
5.2 硬件与软件协同优化
硬件和软件将更加紧密地协同工作,软件开发者可以通过特殊的指令和接口,更好地控制多线程的执行。例如,软件可以向硬件提供更多的线程优先级信息,硬件根据这些信息进行更精准的线程调度。
5.3 适应新兴应用场景
随着人工智能、大数据等新兴技术的发展,多线程技术将不断适应这些新的应用场景。例如,在人工智能训练中,需要处理大量的并行计算任务,多线程技术可以提高计算效率,减少训练时间。
下面是一个 mermaid 流程图,展示未来多线程技术发展的主要趋势:
graph LR;
A[集成化与智能化] --> B[自动选择多线程模式];
A --> C[机器学习辅助调度];
D[硬件与软件协同优化] --> E[软件控制线程优先级];
D --> F[硬件精准调度];
G[适应新兴应用场景] --> H[人工智能计算加速];
G --> I[大数据处理优化];
B --> J[未来多线程技术];
C --> J;
E --> J;
F --> J;
H --> J;
I --> J;
总之,芯片多处理器中的多线程技术在不断发展和演进,不同类型的多线程技术各有优劣,适用于不同的场景。通过对这些技术的深入理解和优化,我们可以更好地利用多线程技术提高处理器的性能和资源利用率,满足未来各种复杂应用的需求。开发者在选择和应用多线程技术时,需要综合考虑性能、成本、应用场景等多方面因素,做出最合适的决策。
超级会员免费看
956

被折叠的 条评论
为什么被折叠?



