课程
CH05
第五章:指令级并行及其开发-硬件方法
指令级并行概念
- 开发ILP的两种途径(资源重复,流水线技术);
- 开发ILP的方法
- 基于硬件的动态开发方法,基于软件的静态开发方法:
流水线研究的并行技术以及所克服的停顿
- 流水线调度、循环展开、寄存器换名、指令动态调度、动态分支预测、瞻、多指令流出;
衡量流水线最高性能指标(CPI)
- 实际CPI和理想CPI的关系;
指令动态调度
- 相关概念
- Tomasulo算法基本原理、基本思想
- 算法的三个阶段(流出、执行、写回)
- 基于Tomasulo算法的MIPS处理器浮点部件的基本结构的工作原理及相应指令分析
- 保留站7个字段的含义及其对应指令的应用
动态分支预测技术
- 几种方法:采用分支历史表BHT、分支目标缓冲器BTB、基于硬件的前瞻执行
- 前瞻执行基本思想(ROB)与Tomasulo算法的联系与区别
- 前瞻执行基本思想(ROB)的4个阶段:流出、执行、写记过、确认
多指令流出技术
- 引入目的:提高CPI
- 常用的技术:超流水线、超长指令字VLIW
指令级并行的概念
指令级并行:指指令之间存在的一种并行性,利用它,计算机可以并行执行两条或两条以上的指令。(前提是不相关)(ILP:Instruction-Level Parallelism)
开发ILP的两种途径
- 资源重复,重复设置多个处理部件,让它们同时执行相邻或相近的多条指令;
- 采用流水线技术,使指令重叠并行执行。
流水线研究的并行技术以及所克服的停顿
| 技术 | 所克服的停顿 |
|---|---|
| 基本流水线调度 | 数据先写后读相关停顿 |
| 循环展开 | 控制相关停顿 |
| 寄存器换名 | 数据写后写和先读后写相关停顿 |
| 指令动态调度(记分牌和Tomasulo算法) | 各种数据相关停顿 |
| 动态分支预测 | 控制相关停顿 |
| 前瞻 | 所有数据/控制相关停顿 |
| 多指令流出(超标量和超长指令字) | 提高理想CPI |
开发ILP的方法
- 主要基于硬件的动态开发方法
- 基于软件的静态开发方法
流水线处理机的实际CPI(执行一条指令所需要的时钟周期数)
- 理想流水线的CPI加上各类停顿的时钟周期数:
CPI流水线 = CPI理想 + 停顿结构冲突 + 停顿数据冲突 + 停顿控制冲突
- 理想CPI是衡量流水线最高性能的一个指标。
IPC:Instructions Per Cycle(每个时钟周期完成的指令条数)
指令动态调度
在程序的执行过程中,依靠专门硬件对代码进行调度,减少数据相关导致的停顿。(前面指令的阻塞不影响后面指令的继续前进)
到目前为止我们所使用流水线(传统的5级流水线)
- 指令按序流出按序执行
- 运算通路只有一条
- 只有一个配置
- 每一条指令都要经过流水线的五段(无论是否需要MEM)
动态调度
- 指令乱序执行
- 实现多配置
- 每一条指令都要经过流水线的四段(流出、读数、执行、写回)
动态调度的核心思想:
- 允许就绪指令越过前面的停顿指令,率先投入运行,即乱序执行
- 为了支持乱序执行,需要对ID阶段进行改造,因为就绪指令就是在ID阶段被阻塞的
- 为了改造ID,需要分析ID阶段的约束条件和存在的问题:
约束条件:ID段指令必须按序执行(译码),前一条尚未译码后续指令就无法进行冲突检测
存在问题:这个这段必须按序执行,前提又要先检测,导致停顿增加
- 解决方法:将ID阶段拆分为两个阶段
Issue:对应之前的ID阶段,但精简操作,只做最必要的事:如指令译码、资源冲突检测。这一阶段仍是按序执行的,并且,在这一阶段停顿的指令,同样会阻塞后面的所有指令(比如因为资源冲突而未能发射的指令阻塞了后面所有的指令)。 但这一阶段不再检测所有数据冲突,因此不管就绪还是非就绪的指令,都有机会发射出去。
Read operands:等待数据冲突消除,然后读取操作数。 这一阶段检测数据冲突,也是乱序执行实际发生的位置:非就绪指令会停顿在这一阶段,就绪指令会直接投入运行
- 不管是什么样的动态调度流水线,都要将ID做这样的拆分,差别主要是如何管理已发射、未就绪的指令:记分牌算法使用记分牌,Tomasulo算法使用保留站
Tomasulo算法
核心思想
- 记录和检测指令相关,操作数一旦就绪就立即执行,把发生RAW冲突的可能性减少到最小;
- 通过寄存器换名来消除WAR冲突和WAW冲突。
换名通过保留站实现,它保存正在执行指令所需的操作数
总结:指令流出,操作数若还没计算出来,则该指令中相应的寄存器换名为产生这个操作数的保留站的标识。即指令流出到保留站,操作数寄存器要么就绪要么换成保留站的标识,此时已和该寄存无关,后面指令对该寄存器写操作则不会产生WAR冲突)。
指令执行的步骤:
使用Tomasulo算法的流水线需3段(流出—执行—写回)
流出:从指令队列的头部取一条指令(完成两个工作:分析源操作数和预约结果存放)(分析操作数从哪里来)
- 如果该指令的操作所要求的保留站有空闲的,就把该指令送到该保留站(设为r)。
- 如果其操作数在寄存器中已经就绪,就将这些操作数送入保留站r。
- 如果其操作数还没有就绪,就把将产生该操作数的保留站的标识送入保留站r。
- 一旦被记录的保留站完成计算,它将直接把数据送给保留站r。
(寄存器换名(换成保留站的标识)和对操作数进行缓冲,消除WAR冲突)
- 完成对目标寄存器的预约工作(分析 结果要到哪里去 ,将之设置为保留站r的结果,这相当于完成了写操作(预约))(由于指令按序流出,当多条指令写同一个结果寄存器,最后留下的一定是最后一条指令的,即消除了写后写冲突)(消除了WAW冲突)
- 如果没有空闲的保留站,指令就不能流出。

执行
- 当两个操作数都就绪后,本保留站就用相应的功能部件开始执行指令规定的操作(即依靠推迟方法解决RAW冲突,由于结果数据是从其产生的部件(保留站)直接送到需要它的地方,因此已经是最大限度地减少了RAW冲突影响)。
- load和store指令的执行需要两个步骤:
计算有效地址(要等到基地址寄存器就绪)
把有效地址放入load或store缓冲器,load执行的条件是存储器部件就绪,而store指令在执行前必须等要存入存储器的数据到达。通过按序进行有效地址计算确保程序的顺序,有助于避免访问存储器的冲突。
写结果
- 功能部件计算完毕后,就将计算结果放到CDB上,所有等待该计算结果的寄存器和保留站(包括store缓冲器)都同时从CDB上获得所需要的数据。

基于Tomasulo算法的MIPS处理器浮点部件的基本结构:


保留站的7个字段
Op:要对源操作数进行的操作
Qj,Qk:产生源操作数的保留站号或者0,0(就绪,操作数放在Vj或Vk或不需要操作数)
Vj,Vk:源操作数的值
- 对于每一个操作数来说,V或Q字段只有一个有效。
- 对于load来说,Vk字段用于保存偏移量。
Busy:为“yes”表示本保留站或缓冲单元“忙”
A:仅load和store缓冲器有该字段。开始是存放指令中的立即数字段,地址计算后存放有效地址。
Qi:寄存器状态表
- 每个寄存器在该表中有对应的一项,用于存放将把结果写入该寄存器的保留站的站号。
- 为0表示当前没有正在执行的指令要写入该寄存器,也即该寄存器中的内容就绪。否则当数据未就绪的时候展示该数据来源对应的保留站的标志或站号。
动态分支预测技术
动态预测:在程序运行时,根据分支指令过去的表现来预测其将来的行为。(预判结果处理、预测有效性、分支开销的影响因素等)
采用分支历史表 BHT
最简单的动态分支预测方法。
用BHT来记录分支指令最近一次或几次的执行情况(成功还是失败 ),并据此进行预测。
只有1个预测位的分支预测 (只记录分支指令最近一次的历史)
- 记录分支指令最近一次的历史,BHT中只需要1位二进制位。(最简单)
- 上次分支成功-----则分支预测下次成功
- 上次分支失败-----则分支预测下次失败
采用两位二进制位来记录历史
- 可提高预测的准确度
- 研究结果表明:两位分支预测的性能与n位(n>2)分支预测的性能差不多。

采用分支目标缓冲器BTB
目标:将分支的开销降为 0(在IF段获取分支目标地址,顺序下一条指令地址,以及预测的结果)
方法:分支目标缓冲
- 将分支成功的分支指令的地址和它的分支目标地址都放到一个缓冲区中保存起来,缓冲区以分支指令的地址作为标识。
- 这个缓冲区就是分支目标缓冲器(Branch-Target Buffer,简记为BTB,或者分支目标Cache(ranch-Target Cache)。
好处:避免 CPU 每次执行分支跳转时重新计算目标地址
缓冲区:联想cache的组织映射方式(直接映射、组相连映射、全相连映射)

采用BTB后,在流水线各个阶段所进行的相关操作:

如果预测错误或者在BTB中没有匹配的项且分支成功,会有至少2个时钟周期的延迟,因为对BTB的项进行修改时,需要停止取指令,所以取新的指令又要花费一个时钟周期
基于硬件的前瞻执行ROB
Tomasulo算法:
- 通过寄存器换名、优化指令并行,并能处理数据依赖,但缺乏控制相关的处理;如果分支指令流出,该算法须等待分支指令执行结果或不等待但导致不精确处理;
- 此外,BTB只能准确预知分支但不能满足并行流水的速度(可能一个周期执行一个指令。)
- 乱序提交指的是一旦指令执行完毕且可以写回(记分牌可能因为读后写冲突而不允许写回),那就立刻写回。
- 一旦发生意外,硬件很难恢复现场,因为是乱序执行-----怎么处理?
前瞻执行(speculation)的基本思想:
- 对分支指令的结果进行猜测,并假设这个猜测总是对的,然后按这个猜测结果取指、流出和执行后续的指令。只是执行指令的结果不是写回到寄存器或存储器,而是写入一个称为再定序缓冲器ROB(ReOrder Buffer)中 。等到相应的指令得到“确认”(commit)(即确实是应该执行的)之后,才将结果写入寄存器或存储器。
- 重排序缓存的目的是让乱序执行的指令被顺序地提交
- 在处理机还没判断分支指令能否执行之前就提前执行,以克服控制相关
关键思想
- 允许指令乱序执行,但必须顺序确认。在指令被确认之前,不允许它进行不可恢复的操作。
- 只有确认以后的结果才是最终结果。加入指令确认阶段需要一套额外的硬件缓冲来保存那些执行完毕但未经确认的指令及其结果
- 不同点在于Tomasulo算法中,一旦指令结果写到目的寄存器,下面的指令就会从寄存器文件中得到数据。而对于前瞻执行,直到指令确认后,才最终更新寄存器文件。

结合ROB的Tomasulo主要有三点改动:
- 一是增加了Reorder Buffer(即ROB);
- 二是CDB总线不再直通逻辑寄存器堆,而是直通ROB;
- 三是指令需要从ROB读取数据。ROB在这里就像是一个FIFO队列,指令在发射时入队,在提交时出队。
采用前瞻执行机制后,指令的执行步骤
流出
- 从浮点指令队列的头部取一条指令。
- 如果有空闲的保留站(设为r)且有空闲的ROB项(设为b),就流出该指令,并把相应的信息放入保留站r和ROB项b。
- 如果保留站或ROB全满,便停止流出指令,直到它们都有空闲的项。
执行
- 如果有操作数尚未就绪,就等待,并不断地监测CDB。(检测RAW冲突)
- 当两个操作数都已在保留站中就绪后,就可以执行该指令的操作。
写结果
- 当结果产生后,将该结果连同本指令在流出段所分配到的ROB项的编号放到CDB上,经CDB写到ROB以及所有等待该结果的保留站。保留站也可以从ROB直接读到结果而不需要CDB。
- 释放产生该结果的保留站。
- store指令在本阶段完成,其操作为:
如果要写入存储器的数据已经就绪,就把该数据写入分配给该store指令的ROB项。
否则,就监测CDB,直到那个数据在CDB上播送出来,才将之写入分配给该store指令的ROB项
确认
- 对分支指令、store指令以及其它指令的处理不同:
- 其它指令(除分支指令和store指令)
当该指令到达ROB队列的头部而且其结果已经就绪时,就把该结果写入该指令的目的寄存器,并从ROB中删除该指令。
- store指令
处理与上面的类似,只是它把结果写入存储器。
- 分支指令
当预测错误的分支指令(执行结果发现预测错误)到达ROB队列的头部时,清空ROB,并从分支指令的另一个分支重新开始执行。(错误的前瞻执行)
当预测正确的分支指令到达ROB队列的头部时,该指令执行完毕。继续后续指令执行。
多指令流出技术
多流出技术允许在每个时钟周期内流出多条指令,这提高了处理器的指令吞吐率,使CPI(每条指令所需的时钟周期数)可以小于1。这意味着在相同的时间内,处理器可以完成更多的工作。
基本概念:
超标量(Superscalar)–可以乱序,如何加快多条指令的调度
- 是指在CPU中有一条以上的流水线,并且每时钟周期内可以完成一条以上的指令,这种设计就叫超标量技术。 其实质是以空间换取时间。
- 超级标量结构的cpu支持指令级并行,每个周期可以发射多条指令
超流水线
- 是一条指令来实现多个操作的并行执行(通常只有一个控制器)
- 以增加流水线级数的方法来缩短机器周期,相同的时间内超级流水线执行了更多的机器指令
- 多采用简单指令加快速度。
- 但配置了多个功能部件和译码电路。
超长指令字VLIW(不可以乱序,如何加快一个指令字的执行)
- 类似于超级标量,是一条指令来实现多个操作的并行执行,之所以放到一条指令是为了减少内存访问。













