计算机组成原理 —— 指令流水线影响因素分类
- 结构冒险
- 结构冒险的原因
- 数据冒险(同步)
- 数据旁路的原理
- 数据旁路的类型
- 数据旁路的例子
- 控制冒险
- 控制冒险的类型
- 控制冒险的例子
- 解决控制冒险的方法
- 示例分析
- 分支预测的策略
- 超标量和超流水
- 超标量(Superscalar)
- 特点
- 优势
- 示例
- 超流水(Superpipeline)
- 特点
- 优势
- 示例
- 总结
我们今天来看看指令流水线影响因素分类,在这之前,建议大家看看五段式指令流水线,可以点击这里:
https://blog.csdn.net/qq_67693066/article/details/140924178
结构冒险
说白了,就是两个指令要争同一个硬件资源(互斥):
结构冒险(Structural Hazard)是流水线处理器中的一种常见问题,它指的是由于硬件资源不足而导致流水线停顿的现象。结构冒险通常发生在当多条指令试图同时访问同一硬件资源时,例如算术逻辑单元(ALU)、寄存器文件、缓存或内存单元等。这种类型的冒险与数据冒险和控制冒险不同,它们分别由数据依赖性和分支指令引起。
结构冒险的原因
- 资源竞争:
- 如果两条或更多指令试图在同一时钟周期内访问同一硬件资源,但该资源在同一时间只能服务一条指令,那么就会发生结构冒险。
- 资源不足:
- 如果处理器中可用的某种资源数量不足以满足同时执行的指令的需求,那么也会发生结构冒险。
解决上面的办法就是让指令和数据分开来,我们可以用两个不同的Cache来装:
根据这样的思想,可以为我们提供一些解决思路的方法。
数据冒险(同步)
其实数据冒险,和操作系统中的同步类似,两个操作必须保持一前一后的关系,这样才能保证结果的正确:
上图中,第一条指令的结果在WB阶段才会被写回,但是第二条指令在还没等回写就要拿数据进行运算,这样肯定不对。
其实解决方法很简单,我等到结果被写回了我再继续执行:
还有一种方法是,我们经过ALU之后,结果其实就已经出来了,我们可以连一条线,把数据送到下一个指令中,这个就叫数据旁路:
数据旁路(Data Bypassing),也被称为数据转发(Data Forwarding),是一种用于解决流水线处理器中数据冒险的技术。数据旁路允许流水线中的后续指令在早期阶段就接收到所需的数据,而不是等待数据写回到寄存器文件。这样可以避免流水线停顿,提高流水线的效率。
数据旁路的原理
数据旁路的核心思想是在流水线的不同阶段之间直接传递数据,而不是通过寄存器文件。这样可以减少指令之间的延迟,并且避免由于数据冒险导致的流水线停顿。
数据旁路的类型
数据旁路可以发生在流水线的不同阶段,主要有以下几种类型:
-
寄存器写回旁路 (Register Write-Back Bypassing):
- 这种类型的旁路发生在写回阶段(WB),允许正在执行的指令直接从WB阶段获取数据,而不是等待数据写回到寄存器文件。
-
执行阶段旁路 (Execution Bypassing):
- 这种类型的旁路发生在执行阶段(EX),允许后续指令从EX阶段获取数据。
-
译码阶段旁路 (Decode Bypassing):
- 这种类型的旁路发生在译码阶段(ID),允许后续指令从ID阶段获取数据。
-
取指阶段旁路 (Fetch Bypassing):
- 这种类型的旁路发生在取指阶段(IF),允许后续指令从IF阶段获取数据。
数据旁路的例子
假设我们有一个五段式流水线处理器,考虑以下指令序列:
ADD R1, R2, R3
(将R2和R3的和写入R1)SUB R4, R1, R5
(从R1中减去R5并将结果写入R4)
在这个例子中,SUB
指令依赖于ADD
指令的结果。如果没有数据旁路,SUB
指令必须等待ADD
指令的结果写回到寄存器文件R1,然后才能开始执行。
控制冒险
控制冒险(Control Hazard)是流水线处理器中的一种常见问题,它指的是由于分支指令(如条件转移、无条件转移等)导致的流水线停顿现象。控制冒险通常发生在处理器预测分支指令的行为时,如果预测错误,则会导致流水线中的指令序列需要被清空并重新装载正确的指令序列,从而导致性能损失。
控制冒险的类型
-
分支冒险 (Branch Hazard):
- 发生在处理器预测分支指令的结果时。如果预测错误,流水线中已经提前执行的指令将被丢弃,流水线需要重新装载正确的指令序列。
-
子程序调用冒险 (Procedure Call Hazard):
- 发生在调用子程序或函数时,这通常涉及返回地址的保存和新的指令地址的加载。
-
中断冒险 (Interrupt Hazard):
- 发生在处理器响应中断时,这会改变程序的控制流,导致流水线中的指令需要被清空。
控制冒险的例子
假设我们有一个五段式流水线处理器,考虑以下指令序列:
ADD R1, R2, R3
(将R2和R3的和写入R1)BRANCH R4
(如果R4中的值为真,则跳转到地址X)
在这个例子中,BRANCH
指令是一个条件转移指令。如果处理器预测转移不会发生,但实际条件满足,那么流水线中已经提前执行的指令将被丢弃,流水线需要重新装载正确的指令序列。
解决控制冒险的方法
- 分支预测 (Branch Prediction):
- 分支预测是一种硬件技术,用于预测分支指令的结果。准确的预测可以减少控制冒险的影响。
- 分支目标缓冲器 (Branch Target Buffer, BTB):
- 分支目标缓冲器是一种硬件结构,用于存储最近的分支指令和它们的目标地址。这可以帮助预测分支指令的结果。
- 动态调度 (Dynamic Scheduling):
- 动态调度技术可以在运行时选择最优的指令执行顺序,以减少控制冒险。
- 硬件支持:
- 现代处理器设计通常包含硬件支持来检测和解决控制冒险,例如使用分支历史表(Branch History Table, BHT)和分支目标缓冲器(BTB)来提高分支预测的准确性。
示例分析
考虑上述指令序列:
ADD R1, R2, R3
BRANCH R4
为了缓解控制冒险,可以采用分支预测技术:
- 如果处理器预测
BRANCH R4
指令将不会发生转移,那么流水线将继续执行后续指令。 - 如果预测错误,流水线将需要被清空,并重新装载正确的指令序列。
分支预测的策略
- 静态预测:
- 基于简单的规则进行预测,如总是采取或总是不采取分支。
- 动态预测:
- 根据历史行为动态调整预测策略,例如使用分支历史表(BHT)和分支目标缓冲器(BTB)。
- 全局历史预测:
- 使用全局历史表记录最近的分支结果,以帮助预测未来的分支行为。
- 局部历史预测:
- 使用局部历史表记录特定分支指令的历史结果,以帮助预测未来的分支行为。
通过使用分支预测和其他技术,可以显著减少控制冒险对流水线性能的影响。
超标量和超流水
超标量(Superscalar)和超流水(Superpipeline)是两种不同的处理器架构设计,它们旨在通过不同的方法提高处理器的性能。
超标量(Superscalar)
超标量处理器设计允许处理器在一个时钟周期内执行多条指令。这是通过在处理器内部并行执行多个指令来实现的,通常涉及到多个执行单元和指令调度器。
特点
- 多个执行单元:
- 超标量处理器包含多个功能单元(如整数ALU、浮点ALU等),每个单元可以独立执行不同的指令。
- 指令级并行性 (ILP):
- 超标量处理器可以同时执行多条指令,利用指令级并行性提高性能。
- 动态调度:
- 超标量处理器通常包含动态调度器,它可以在运行时选择最优的指令执行顺序,以减少数据冒险。
- 寄存器重命名:
- 寄存器重命名技术可以避免写后写冒险和写后读冒险,通过使用虚拟寄存器来消除数据冒险。
- 分支预测:
- 高级分支预测技术可以帮助减少控制冒险,提高超标量处理器的效率。
优势
- 更高的吞吐量:能够在每个时钟周期执行多条指令。
- 更高的效率:通过并行执行指令来提高处理器利用率。
示例
假设一个超标量处理器包含两个整数ALU和一个浮点ALU。在这种情况下,处理器可以在一个时钟周期内同时执行两条整数指令和一条浮点指令。
超流水(Superpipeline)
超流水是指将指令流水线设计得更深,即增加流水线的级数,从而使得每个阶段的工作量更小。这种方法旨在通过更细致地划分指令执行过程来提高吞吐量。
特点
- 更深的流水线:
- 超流水处理器具有更多的流水线级数,每个阶段的工作量较小。
- 更短的时钟周期:
- 由于每个阶段的工作量更小,因此可以使用更短的时钟周期来保证每个阶段的完成。
- 资源分配:
- 更深的流水线需要更精细的资源分配,以确保流水线的顺畅运行。
- 控制逻辑:
- 需要更复杂的控制逻辑来管理更深的流水线。
优势
- 更高的时钟频率:由于每个阶段的工作量较小,可以使用更高的时钟频率。
- 更高的吞吐量:理论上,更深的流水线可以提高吞吐量。
示例
假设一个五段式流水线处理器,每个阶段需要一个时钟周期来完成工作。如果我们将流水线扩展到十个阶段,每个阶段的工作量将更小,理论上可以使用更高的时钟频率,从而提高吞吐量。
总结
- 超标量侧重于通过并行执行多条指令来提高性能。
- 超流水侧重于通过增加流水线的深度来提高吞吐量。
这两种技术都可以提高处理器的性能,但它们通过不同的方法实现这一目标。在现代处理器设计中,通常会结合使用这两种技术以及其他优化技术来达到最佳性能。
还有一种是超长指令字: