计算机系统结构复习笔记(四)

第四章 指令级并行

本章研究:如何通过各种可能的技术,获得更多的指令级并行性。
硬件(动态)+软件技术(静态)

4.1 指令级并行

指令之间不存在相关时,它们在流水线中是可以重叠起来并行执行的。这种指令序列中存在的潜在并行性称为指令级并行
流水线处理器的实际CPI(平均每条指令使用的周期数)等于理想流水线的CPI加上各类停顿引起的周期数的总和:

\[CPI_{流水线} = CPI_{理想} + 停顿_{结构冲突} + 停顿_{数据冲突} + 停顿_{控制冲突} \]

基本程序块:一段除了入口和出口以外不包含其他分支的线性代码段。
循环级并行:使一个循环中的不同循环体并行执行。
程序顺序:由源程序确定的在完全串行方式下指令的执行顺序。
数据流:指数据值从其产生者指令到其消费者指令的实际流动。

4.2 指令的动态调度

指令调度就是通过改变指令在程序中的位置,将相关指令之间的距离加大到不小于指令执行延迟的时钟数。
静态调度依靠编译器确定并分理处程序中存在相关的指令,然后进行指令调度,并对代码进行优化。
动态调度通过硬件重新安排指令的执行顺序来调整相关指令实际执行时的关系,减少处理器空转。

4.2.1 动态调度的基本思想

到目前为止我们所使用流水线的最大的局限性:指令必须按序流出和按序执行

解决办法:允许乱序执行
我们将5段流水线的译码阶段再分为两个阶段:

流出(Issue,IS):指令译码,检查是否存在结构冲突,只要无结构冲突,指令就推进,所以指令在该阶段是顺序的。
读操作数(Read Operands,RO):等待数据冲突消失(如果有),然后读操作数,此时可能由于冲突造成停顿和跨越,造成执行的乱序。

在前述5段流水线中,是不会发生WAR冲突和WAW冲突的。但乱序执行就使得它们可能发生了。
Tomasulo算法可以通过使用寄存器重命名来消除名相关带来的冲突。
记分牌算法和Tomasulo算法是两种比较典型的动态调度算法。Tomasulo算法是记分牌算法的改进。我们只介绍Tomasulo算法(更常用)。

4.2.2 Tomasulo算法

核心思想:
记录和检测指令相关,操作数一旦就绪就立即执行,把发生RAW冲突的可能性减少到最小;
通过寄存器换名来消除WAR冲突和WAW冲突。硬件动态换名,区别于第三章的编译器静态换名。

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

保留站RS:每个保留站中保存一条已经流出并等待到本功能部件执行的指令(相关信息)。
在一条指令流出到保留站的时候,如果该指令的源操作数已经在寄存器中就绪,则将之取到该保留站中。
如果操作数还没有计算出来,则在该保留站中记录将产生这个操作数的保留站的标识。(体现保留站的意义)

公共数据总线CDB:是该结构中的一条重要的数据通路所有功能部件的计算结果都是送到CDB上,由它把这些结果直接送到(播送到)各个需要该结果的地方。

指令队列:指令部件送来的指令放入指令队列,指令队列中的指令按先进先出的顺序流出

在Tomasulo算法中,寄存器换名是通过保留站和流出逻辑来共同完成的。
当指令流出时,如果其操作数还没有计算出来,则将该指令中相应的寄存器号换名为将产生这个操作数的保留站的标识。指令流出到保留站后,其操作数寄存器号或者换成了数据本身(如果该数据已经就绪),或者换成了保留站的标识,不再与寄存器有关系。

Tomasulo算法具有以下两个特点:
1.冲突检测和指令执行控制是分布的。每个功能部件的保留站中的信息决定了什么时候指令可以在该功能部件开始执行。
2.计算结果通过CDB直接从产生它的保留站传送到所有需要它的功能部件,而不用经过寄存器。

使用Tomasulo算法的流水线需3段:
流出:从指令队列的头部取一条指令。
执行
写结果

Tomasulo算法举例
例4.1 对于下述指令序列,给出当第一条指令完成并写入结果时,Tomasulo算法所用的各信息表中的内容。
L.D \(~~~~~~~~\)F6,34(R2)
L.D \(~~~~~~~~\)F2,45(R3)
MUL.D \(~~~\)F0,F2,F4
SUB.D \(~~~~\)F8,F2,F6
DIV.D \(~~~~~\)F10,F0,F6
ADD.D \(~~~~\)F6,F8,F2
当采用Tomasulo算法时,在上述给定的时刻,保留站、load缓冲器以及寄存器状态表中的内容:

每个保留站有以下几个字段:见图

Op:要对源操作数进行的操作。
Qj,Qk:将产生源操作数的保留站号。等于0表示操作数已经就绪且在Vj或Vk中,或者不需要操作数。
Vj,Vk:源操作数的值。
对于每一个操作数来说,V或Q字段只有一个有效。
对于load来说,Vk字段用于保存偏移量。
Busy:为“yes”表示本保留站或缓冲单元“忙”。
A:仅load和store缓冲器有该字段。开始是存放指令中的立即数字段,地址计算后存放有效地址。

Qi:寄存器状态表。
每个寄存器在该表中有对应的一项,用于存放将把结果写入该寄存器的保留站的站号。
为0表示当前没有正在执行的指令要写入该寄存器,也即该寄存器中的内容就绪。

Tomasulo算法具有两个主要的优点:
冲突检测逻辑和执行是分布的(通过保留站和CDB实现)
消除了WAW冲突和WAR冲突导致的停顿

4.3 动态分支预测技术

所开发的ILP越多,控制相关的制约就越大,分支预测就要有更高的准确度。
本节中介绍的方法对于每个时钟周期流出多条指令(若为n条,就称为n流出)的处理机来说非常重要。

动态分支预测:在程序运行时,根据分支指令过去的表现来预测其将来的行为。

分支预测的有效性取决于:
预测的准确性
预测正确和不正确两种情况下的分支开销

需要解决的关键问题
如何记录分支的历史信息;
如何根据这些信息来预测分支的去向(甚至取到指令)。
在预测错误时,要作废已经预取和分析的指令,恢复现场(就需要提前保存现场),并从另一条分支路径重新取指令。

4.3.1 采用分支历史表 BHT

分支历史表BHT(Branch History Table)或分支预测缓冲器(Branch Prediciton Buffer):
是最简单的动态分支预测方法。 用BHT来记录分支指令最近一次或几次的执行情况(成功或不成功),并据此进行预测。

采用两位二进制位来记录历史:
研究结果表明:两位分支预测的性能与n位(n>2)分支预测的性能差不多。
两位分支预测的状态转换如下所示:

两位分支预测中的操作有两个步骤:
1.分支预测。
当分支指令到达译码段(ID)时,根据从BHT读出的信息进行分支预测。
若预测正确,就继续处理后续的指令,流水线没有断流。否则,就要作废已经预取和分析的指令,恢复现场,并从另一条分支路径重新取指令。(详见前瞻执行)
2.状态修改。

BHT方法只在以下情况下才有用:
判定分支是否成功所需的时间大于确定分支目标地址所需的时间。(预测成功能够真正推进)

4.3.2 采用分支目标缓冲器BTB

将分支成功的分支指令的地址和它的分支目标地址都放到一个缓冲区中保存起来,缓冲区以分支指令的地址作为标识。这个缓冲区就是分支目标缓冲器

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

BTB的另一种形式:
在分支目标缓冲器中存放一条或者多条分支目标处的指令。
有三个潜在的好处:
更快地获得分支目标处的指令;
可以一次提供分支目标处的多条指令,这对于多流出处理器是很有必要的;
使我们可以进行称为分支折叠(branch folding)的优化。

4.3.3 基于硬件的前瞻执行

前瞻执行(speculation)的基本思想:对分支指令的结果进行猜测,并假设这个猜测总是对的,然后按这个猜测结果继续取、流出和执行后续的指令。只是执行指令的结果不是写回到寄存器或存储器,而是放到一个称为ROB(ReOrder Buffer)的缓冲器中。等到相应的指令得到“确认”(commit)(即确实是应该执行的)之后,才将结果写入寄存器或存储器。

对Tomasulo算法加以扩充,就可以支持前瞻执行。把Tomasulo算法的写结果和指令完成加以区分,分成两个不同的段:写结果,指令确认

实现前瞻的关键思想:允许指令乱序执行,但必须顺序确认。

采用前瞻执行机制后,指令的执行步骤:(在Tomasulo算法的基础上改造的 )
流出
执行
写结果
确认

前瞻执行&Tomasulo算法
前者是后者的改进,前者所需的硬件更复杂。
前者通过ROB实现了指令的顺序确认,后者是为了乱序执行。
前者能够实现精确异常,后者可能会产生不精确异常。
前者容易地推广到整数寄存器和整数功能单元上。

4.4 多指令流出技术

一个时钟周期内流出多条指令, CPI<1。
单流出和多流出处理机执行指令的时空图对比

4.4.1 基于静态调度的多流出技术

4.4.2 基于动态调度的多流出技术

4.4.3 超长指令字技术(VLIW)

4.4.4 多流出处理器受到的限制

4.4.5 超流水线处理机

4.5 循环展开和指令调度

充分开发指令之间存在的并行性,找出不相关的指令序列,让它们在流水线上重叠并行执行。
增加指令间并行性最简单和最常用的方法:
开发循环级并行性——循环的不同迭代之间存在的并行性。
在把循环展开后,通过重命名和指令调度来开发更多的并行性。

假设采用第3章的5段整数流水线:
例4.6 对于下面的源代码,转换成MIPS汇编语言,
在不进行指令调度和进行指令调度两种情况下,分析其
代码一次循环所需的执行时间。
for (i=1; i<=1000; i++)
\(~~~~~~\)x[i] = x[i] + s;
把该程序翻译成MIPS汇编语言代码:

不进行指令调度的情况下,程序的实际执行情况:

每个元素的操作需要10个时钟周期,其中5个是空转周期。

指令调度以后,程序的执行情况如下:
把DADDIU指令调度到了L.D指令和ADD.D指令之间的“空转”拍。
把S.D指令放到了分支指令的延迟槽中。
对存储器地址偏移量进行调整。

一个元素的操作时间从10个时钟周期减少到6个,其中5个周期是有指令执行的,1个为空转周期。

DADDIU、空转和BEN这3个时钟周期都是附加的循环控制开销:
循环展开技术
把循环体的代码复制多次并按顺序排列,然后相应调整循环的结束条件。

通过循环展开寄存器重命名指令调度,可以有效地开发出指令级并行。

4.5.2 静态超标量处理机中的循环展开

posted @ 2023-06-21 15:54  Midvoy_尺  阅读(898)  评论(3编辑  收藏  举报