【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上

第五章 硬件方法的指令并行

该文章针对的指令集为MIPS的五段流水,即IF、ID、EX、MEM、WB。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第1张图片

流水线的分类方法有多种,这里主要要了解的为指令乱序,该概念在流水线的分类中被提及到:
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第2张图片

顺序流水会有互锁的现象,主要是为了保证流水线的输出顺序和输入顺序相同。而乱序流水线则不必要,是一种更加追求效率但更加难实现的流水方式。

一、指令级别的并行

指令级别的并行的开发可以分为两类,基于软件和基于硬件,同时,这两种优化并非绝对的,可以是相互关联的(例如后面的Tomasulo的算法,一定程度上也有forwarding的思想)。

CPI的组成部分如下,因此如果想要尽可能的减少CPI,则需要优化三种冲突。
在这里插入图片描述

二、相关与指令并行

首先要确定一点,相关是程序的属性,也就是说一个程序写出来必然是有相关性的,若一个程序毫无相关性这几乎是不可能的。因此,写出程序那么必然会带有相关性。相关性分为三类:结构相关、数据相关和控制相关。而流水线的三种冲突也是相关性所导致的。这三种冲突分别是结构冲突、数据冲突和控制冲突。对三种相关和冲突的介绍并非本章重点内容,仅做回顾。

(1)结构相关和结构冲突

该冲突的产生原因是由于硬件设备的争抢所导致的。例如,流水线上有多条的浮点加法运算,但计算机中的硬件只有一个浮点加法器,那么这种情况下就会产生结构冲突,即浮点加法的指令不可能一瞬间就执行完成,故会花费一定的时间在EX段,因此浮点加法器便会供不应求,那么就会产生结构冲突。

(2)数据相关和RAW、WAW、WAR冲突

数据冲突的产生原因包括两部分,数据相关和名相关。数据相关的定义为:

对于两条指令i(在前,下同)和j(在后,下同),如果下述条件之一成立,则称指令j与指令i数据相关。

(1)指令j使用指令i产生的结果;

(2)指令j与指令k数据相关,而指令k又与指令i数据相关。

数据冲突会导致RAW(read after write,即写后读)定义如下:

RAW是指令2使用了指令1的结果,而在指令1写入寄存器之前就对寄存器进行了读取的操作,因此会读到错误的数据,产生RAW冲突。

示例如下:粉色字的部分为RAW冲突,在普通的MIPS五段流水中,这是最常出现的类型,即LOAD指令写回F0的内容应该在WB段,而LOAD指令紧跟着ADD指令,ADD指令读取F0寄存器在ID段,因此会读的时候LOAD指令还未进行写操作,故会出现错误。这里的解决方法在前一章有过叙述:例如静态调度、forwarding技术。
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第3张图片

数据相关之所以带有“数据”两个字,是因为其本质是数据流的相关性。例如对寄存器的访问遵循一定的顺序,本质上就是数据流具有固定的顺序,而各条指令无论如何优化,需要保证其逻辑的正确性。例如上述的两种冲突,就是由于要保证其数据流的正确性,故流水线会因冲突而中断,不得不进行暂停等待(这里不考虑各种优化,只是单纯的指令流水)。而名相关与数据相关并不相同,名相关两条指令使用了相同的寄存器,但其并没有数据上的相关性。因此名相关的定义为:

两条指令使用相同的名,但是它们之间并没有数据流动,则称这两条指令存在名相关

名相关分为两类:反相关和输出相关,反相关的概念和实例如下:

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第4张图片

再次强调,这里的相关是名相关而不是数据相关,因此是不存在数据流之间的冲突的,也因此两条指令之间的F6寄存器并不是数据上的冲突,而是会发生读后写(write after read,WAR)冲突。但还是在上述的五段流水指令中,读后写冲突并不会发生。因为读后写是指令2在指令1之前就进行了写操作(可以看上面的例子),但上述的流水并不会产生乱序,因此不会产生该冲突。所以不难发现,读后写冲突是需要指令(1)写操作提前,或者(2)指令顺序得到重拍。实质上,产生该冲突的原因就是指令乱序等原因,导致了数据流的冲突,也就使得原本两条没有产生数据流冲突的指令存在了数据流上的冲突。

输出相关:

如果指令2和指令1写相同的名,则称指令1和2发生了输出相关。

WAW(write after write)冲突:WAW是指令1和指令2都使用了相同的目的寄存器,但在指令1写入之前,指令2就对目的寄存器写入了数据,因此会导致写入顺序的错误。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第5张图片

上图为输出相关,在普通MIPS五段流水中不会出现WAW冲突。

输出相关也不会在上述的五段流水中出现,因为若没有指令乱序,那么写回段的执行必然是前一条指令早于后一条指令(互锁),也就不会产生输出相关。但如果支持指令乱序,那么就会出现后一条指令早于前一条指令执行完成,也就会产生写寄存器的顺序不同。输出相关产生的冲突被称为写后写(write after write,即WAW)冲突,其产生的原因为流水线中(1)不止一个段可以进行写操作(相比于上述的只能在WB段进行写回操作),或者是(2)指令乱序。

一些助记的技巧:RAW冲突是本身的顺序应当是先读再写,但由于数据冲突而导致了指令的操作顺序成为了先写再读,WAR冲突本应该是先读再写,但由于乱序等原因使得数据流变为了先写再度,因此产生了冲突。

(3)控制相关和控制冲突

控制相关是由于分支指令导致的,典型的例子就是if-then的形式。为了保证程序应有的执行顺序,必须严格按控制相关确定的顺序执行。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第6张图片

分支指令会导致向两个不同的地址进行跳转,因此在流水线中,真正得到要跳转的地址并更改PC是在branch的EX段和MEM段完成的(见开头图示),那么对后面的指令,可能就会出现白白执行的问题。即,分支失败的话指令应该是顺序执行,成功的话会是跳转执行,但实际上你并不知道会向着哪个方向执行,故必然会出现浪费的情况(虽然这种浪费的情况也是一种解决分支冲突的方式,会在后面的内容提及),因此可以看到分支几乎不可避免的会出现STALL的情况。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第7张图片

在流水线中,控制冲突可能比数据相关会造成更大的影响。因为在一段程序中,往往5-7条指令就会存在一个分支,因此控制相关的出现频率相当高。

言归正传,我们可以从两个方面去解决相关的问题,以此来解决冲突的问题。(1)可以保持相关,但避免冲突的产生。例如静态调度(软件),或者动态调度(硬件,本章要重点提及的内容);或者(2)通过代码变换,消除相关。在这一章,可以通过改变指令执行顺序来进行优化(即乱序),同时,控制相关并不是一个必须严格保持的关键属性,即保证程序的正确性即可。那么,怎么能确保程序的正确性呢?或者说,有什么属性是必须遵守的呢?对于程序正确执行来说,保持异常行为和数据流是最重要的。

保持异常行为(Exception Behavior)是指:无论怎么改变指令的执行顺序,都不能改变程序中异常的发生情况。通常可以认为,改变顺序后不会增添新的异常。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第8张图片

该例子中,如果只考虑LW指令与前两条指令的数据相关性,LW指令可以移到BEQZ指令之前,但会因为没有遵循控制相关,则产生异常(Memory Protection Exception) –访问地址=0。

数据流(Data Flow):指数据值从其产生者指令到其消费者指令的实际流动。

数据流的理解在上文解释冲突和相关时提到过,但似乎是更为狭义的数据流的概念:因为在普通的、不含乱序的五段流水中,数据流出的顺序应当和流入的顺序相同。但是在支持乱序的情况下,应该深入为生产者指令到消费者指令的数据流动,例如指令2需要使用指令1的结果。分支指令使得数据流具有动态性,因为它使得给定指令的数据可以有多个来源。仅仅保持数据相关性是不够的,只有再加上保持控制顺序,才能够保持程序顺序。

刚刚提到,控制相关并不是需要严格保持的关键属性,有时候不遵守控制相关既不影响异常行为,也不改变数据流:
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第9张图片

总结的来说,如果要保证程序的正确性,最核心的就是不要在调换指令顺序后产生新的异常,且要保证数据流是从生产者指令到消费者指令的流动方向。

三、指令的动态调度

和之前的静态调度对比,静态调度是依靠编译器对软件进行静态调度,改变指令的顺序,以达到减少相关和冲突的目的。而动态调度则是在程序的运行中进行调度。动态调度可以解决一些编译器不明的问题,例如存储器的内容,也能够使本来是面向某一流水线优化编译的代码在其他的流水线(动态调度)上也能高效地执行。但缺点显而易见,会大幅度提升硬件的复杂程度。

思考前一章的内容,会发现两种冲突都是在译码段检测出来的,也只有当两种冲突都不存在时,才会让指令流出,即互锁的概念。但在可以乱序执行的情况下,我们将ID段细分为两段:

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第10张图片

即,只要没有结构冲突,那么就可以让指令流出,流出后的指令一旦获得操作数,那么就立即执行。也就是说,不再在ID段等到所以冲突都消失了再进行指令流出,而是只要没有结构冲突便可以流出。这样的好处是可以加快指令的处理速度。由于互锁的存在,可能后续的指令和前面的指令并不相干,但仍会被阻塞,因此导致了效率的降低。但是若可以乱序执行,那么就可以将与冲突无关的指令直接执行,提高效率。可以说,乱序指令执行有点流水线中并行的感觉,即动态流水支持多条指令处于执行态中。

好像到现在,一切都很完美:乱序的执行导致之前会被阻塞的指令得到了提前处理,提高流水效率。但乱序的出现,会导致上述的两种冲突:WAW和WAR冲突的出现。两种冲突的产生原因在上文已有详细描述,不在此赘述。下面介绍两种动态调度的算法:记分牌和Tomasulo。

(一)记分牌(Scoreboard)

记分牌算法把ID段分成两个段:流出和读操作数;允许多条指令同时处于执行段。记分牌全面负责和管理这指令的流出和执行,也包括检测所有的冲突。在没有结构冲突时,尽可能早地执行没有数据冲突的指令。如果某条指令被暂停,而后面的指令与流水线中正在执行或被暂停的指令都不相关,那么这些指令就可以跨越它们,继续流出和执行下去(out of order)。

记分牌的处理步骤分为四部分:流出、读操作数、执行和写结果。注意这里并不是说指令是四段流水的,只是记分牌的处理过程是这样的。、

处理过程
(1)流出:

指令能否流出的关键在于是否存在结构冲突和WAW冲突,若不存在结构和WAW冲突,那么指令一定可以流出。这样的操作解决了WAW冲突,毕竟存在WAW便不能流出,那么一定可以消除WAW冲突。

(2)读操作数:

在流出之后,指令需要读取操作数,并将操作数放到寄存器中,这里的功能部件表的Fi、j、k和Rj、k均和寄存器相关。记分牌监测源操作数的可用性,一旦数据可用(即Rj、k是否为yes),它就通知功能部件从寄存器读出源操作数并开始执行(动态地解决了RAW冲突),否则等待。数据可用是指:如果所有前面已流出且还在执行的指令都不对该寄存器进行写操作,则该寄存器的数据是可用的

(3)执行:

取到操作数后,功能部件开始执行。当产生出结果后,就通知记分牌它已经完成执行。

(4)写结果:

记分牌一旦知道执行部件完成了执行,就检测是否存在WAR冲突。如果不存在WAR冲突,或者原有的WAR冲突已消失,记分牌就通知功能部件把结果写入目的寄存器,并释放该指令使用的所有资源。如果检测到WAR冲突,就不允许该指令将结果写到目的寄存器,这发生在以下情况:前面的某条指令(按顺序流出)还没有读取操作数,而且其某个源操作数寄存器与本指令的目的寄存器相同。在这种情况下,记分牌必须等待,直到该冲突消失。简而言之,写结果阶段会针对RAW操作进行处理:如果存在WAR**(指令2要写寄存器,指令1因与其前面的指令存在冲突而被延后执行,由于乱序的存在,导致指令1还没有进行读寄存器,那么此时指令2就不可以写寄存器)**,那么就会等待,直到WAR冲突消失。

总而言之,WAW和结构冲突在流出的部分被解决,WAR冲突在写结果的时候被解决,RAW冲突是读操作数时判断是否数据可用时被解决的。该过程都是动态的,出现的冲突是指令不断执行过程中被解决的

记分牌结构

数据结构分成了三部分:首先是指令状态表,记录指令进入到哪一阶段,很像时空图。但这里主要是以阶段来记录时间。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第11张图片

然后是功能部件状态表,详细的内容见图。第一项是该部件是否被使用,例如一台机器中有两个加法器,那么功能部件ADD就会有两项,BUSY标识该部件是否被使用。2-5项就很像一条指令,存在操作、目的和源寄存器。Q可以理解为该寄存器受到那个部件的阻碍,导致还没有得到数据。R是表示源寄存器中的操作数是否就绪且未被取走,要判断R的值需要看具体的时刻。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第12张图片

最后是结果寄存器状态表,该表表示了寄存器目前被哪个部件占用。

实例

下面看一段实例,该积分表发生在执行完LD1,LD2还未写回到目标寄存器的时刻:
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第13张图片

分析执行到那个段,可以考虑发生了哪些冲突。例如在流出段,就需要检测是否存在结构和WAW冲突;读操作数时检查RAW,写结果时检查WAR。

先分析指令状态表,两条LD指令的结果是初始条件,MULT指令此时可以流出,因为不存在结构和WAW冲突。但是其F2寄存器与上一条指令存在RAW冲突,因此需要等待,不能读取操作数。SUB指令同理。DIV则是与F0有RAW相关。最后的ADD与SUB存在结构冲突,即只有一个F6,但是SUB先使用了,ADD就不可以使用。

再分析功能部件状态表:每条指令流出后便可以进入功能部件状态表,根据使用的部件,将BUSY更改为yes,同时将指令内容放入2-5行(没有就不写)。之后是Q的两列,分别对应前面的两个源寄存器,同样也是没有寄存器便不写。如果出现了冲突而导致该寄存器读取不到想要的数据,则在对应Q的位置写上部件的名称。例如:Mult1的地方对应MULT指令,该指令的F2存在RAW冲突,该冲突来源于LD,即Integer部件,因此将Qj写为Integer。最后的两列R即寄存器内操作数是否就绪且未被取走。对于第一行,已经结束执行,故Rj填入no。第二行,F2由于冲突还未获得操作数,而F4已经读取到了操作数并且就绪可以操作,因此写yes。第四行,F2由于RAW冲突得不到操作数,因此为no,而F6已经准备就绪故为yes。第五行同理。

最后是结果寄存器状态表:此时在运行的为2、3、4、5条指令,将部件写入对应的指令的目标寄存器下即可。

下面是上个实例的进一步推演,给出的是MULT写结果之前的记分牌的状态:
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第14张图片

此时执行的指令为3、5、6,可以看到SUB已经先于MULT执行完成,这就导致了指令乱序的结果,也是我们想达成的。

分析指令状态表,前三行可以认为是前提条件,现在从第四行开始分析:SUB指令和LD的RAW冲突随着LD执行结束已经消失,因此可以执行到结束。DIV的F0存在RAW冲突,但不存在结构冲突和WAW冲突,因此可以流出,但不能取操作数。ADD指令和DIV存在WAR冲突,即DIV还未将F6的内容送入目标寄存器,ADD就将覆盖F6寄存器,会产生读后写冲突,因此不能写结果。故指令状态表如图所示。

然后分析功能部件状态表:前五列和之前分析的一样,Q的部分只有DIV的F0存在了RAW冲突,Qj需要等待Mult1的数据,因此填入Mult1.对于R的最后两列,第二行只差写结果,故R均为no。第四行同理。第五行的F0需要等待MULT的写入,因此为no。

可以总结一下,RAW的R基本都是一个yes一个no,且Q的位置会写入功能部件,WAR冲突则R都为no,Q不会写入功能部件。而WAW则不会流入,故不做考虑。原因上述已经分析。

记分牌的特点:

可实现乱序,这毋庸置疑。由于乱序,会导致WAW、WAR冲突,且对之前的forwarding硬件并没有得到应用,因此仍有改进空间。

(二)Tomasulo

该算法在许多的指令级别并行的现代处理机中都采用了该算法或者变形,因此效果良好,且广泛应用。同时该算法可以认为是记分牌的进一步优化:(1)记录和检测指令相关,操作数一旦就绪就立即执行,把发生RAW冲突的可能性减少到最小(2)通过寄存器换名来消除WAR冲突和WAW冲突。

下面为换名解决WAR和WAW冲突的操作,要注意,这里的WAR和WAW并非一定会出现,因为需要指令乱序或者多段写操作,但该段代码看不出是否存在乱序,因为不知道其时空图,故只是对可能存在的冲突进行提示。
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第15张图片

算法的主要结构:该结构为采用Tomasulo算法的MIPS浮点部件基本结构。

基本结构

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第16张图片

(1)保留站

简而言之,保留站是在ID段的内容,相当于特殊的寄存器,存储的是指令的内容(只记录源寄存器,因为这里是使用换名技术解决冲突,因此是将需要换名的指令的源寄存器在保留站中就进行换名,且换为保留站的唯一标识字段)。寄存器换名是通过保留站和流出逻辑来共同完成的。当指令流出时,如果其操作数还没有计算出来,则将该指令中相应的寄存器号换名为将产生这个操作数的保留站的标识。指令流出到保留站后,其操作数寄存器号或者换成了数据本身(如果该数据已经就绪),或者换成了保留站的标识,不再与寄存器有关系。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第17张图片

(2)CDB

这部分的内容是将Forwarding技术应用与该算法,即将EX的结构进行广播,若有需要的指令即可取走数据,并不需要等到指令写回才能取得数据,因此达到了旁路技术的效果,非常巧妙。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第18张图片

(3)存储器

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第19张图片

store缓冲器的作用有3个:1.存放用于计算有效地址的分量;2.保存正在进行的store访存的目标地址,该store正在等待存储数据的到达;3.保存该store的地址和数据,直到存储部件接收

(4)剩余部件

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第20张图片

简化demo:

这里的Qi相当重要,其标识着进入保留站的指令的目的寄存器的编号。例如MUL进入保留站,那么其目的寄存器F0则会保存在Qi的最后一行,对应F0;ADD进入保留站,则会放到Qi的倒数第二行,即标识着目的寄存器的编号为F2。这也为换名解决冲突提供了条件,毕竟WAW和WAR寄存器均与目的寄存器有关。

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第21张图片

每条指令的执行过程如下:

(1)流出:

从指令队列的头部取一条指令。如果该指令的操作所要求的保留站有空闲的,就把该指令送到该保留站(设为r)。如果其操作数在寄存器中已经就绪,就将这些操作数送入保留站r。如果其操作数还没有就绪,就把将产生该操作数的保留站的标识送入保留站r(换名技术)。一旦被记录的保留站完成计算,它将直接把数据送给保留站r(定向技术的应用)。(寄存器换名和对操作数进行缓冲,消除WAR冲突)完成对目标寄存器的预约工作(消除了WAW冲突)如果没有空闲的保留站,指令就不能流出。(发生了结构冲突)

(2)执行:

当两个操作数都就绪后,本保留站就用相应的功能部件开始执行指令规定的操作。load和store指令的执行需要两个步骤:计算有效地址(要等到基地址寄存器就绪)把有效地址放入load或store缓冲器

(3)写结果

功能部件计算完毕后,就将计算结果放到CDB上,所有等待该计算结果的寄存器和保留站(包括store缓冲器)都同时从CDB上获得所需要的数据。

基本结构:

该算法是优化与记分牌的,故指令状态表和结果寄存器状态表与记分牌无异,但功能部件状态表更换为保留站:

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第22张图片

操作流程:

(1)

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第23张图片

(2)

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第24张图片

(3)

【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第25张图片

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

(三) 动态分支预测技术

该项技术为在指向的过程不断地调整预测方向,以此来适应程序的跳转方向。在后面的超标量处理机中,由于一次处理多条指令,遇到分支指令的概率也变大了n倍。因此,如果能够对于分支的变化方法有好的预测,那么就可以很大程度上提高效率。在预测错误时,要作废已经预取和分析的指令,恢复现场,并从另一条分支路径重新取指令

3.1 分支历史表

BHT(Branch History Table)是最简单的预测分支的方法。算法的内容和名字类似,就是对分支的历史使用自动机的方式进行记录。
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第26张图片
第一位如果是1,那么久预测分支成功;如果第一位是0,则预测分支失败。如初始状态是00(预测分支失败),则需要两次预测失败(主要,这里是说预测的结果错误,而不是说预测分支跳转失败)就会跳转到预测分支成功的状态。同理,如果初始态是11,经过两次预测失败就会跳转到预测分支不成功的状态。相当于在00或者11的状态时预测错误,则还会有一次试错的机会,倘若再次预测失败,那么该程序就会预测分支跳转的方向为之前的反方向(连续预测错误两次,则更改预测的方向)。

一般是用两位二进制位来记录历史,首先可以提高预测的准确度(与1位二进制历史比较),同时研究结果表明:两位分支预测的性能与n位(n>2)分支预测的性能差不多。

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

研究结果表明:对于SPEC89测试程序来说,具有大小为4K的BHT的预测准确率为82%~99%。同时BHT可以跟分支指令一起存放在指令Cache中,也可以用一个专门的硬件来实现。但BHT并不是任何时候都可以成功:
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第27张图片

3.2采用分支目标缓冲器BTB

对于高性能流水线,如多流出类的处理机,如果只能预测分支还不够,在准确预测分支的基础上,还要求能快速提供足够的指令流(4-8条)。这也就需要尽早的知道分支是否成功、尽早获得分支目标地址、获得分支目标指令。

对于前述五段流水,是在ID段对BHT访问,所以在ID的末尾可以获得分支目标地址。那如果能再提前一拍得到分支目标地址,分支开销就可以减小为0。即提前得知分支目标地址,就不会再消耗时间去判断。而BTB就可以做到这一点。BTB的思想就是:将分支成功的分支指令的地址和它的分支目标地址都放到一个缓冲区中保存起来,缓冲区以分支指令的地址作为标识。这个缓冲区就是分支目标缓冲器(Branch-Target Buffer,简记为BTB,或者Branch-Target Cache)
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第28张图片
(最后一段话是用分支目标地址作为下一条指令的PC值)
这就像一个专门为分支预测设置了cache,也同样应用局部性原理。在每次取指令的时候,用该指令的地址与BTB的项目的第一个字段进行比较,如果匹配,则知道该分支指令上一次是分支成功的,据此预测此次也是成功的,而成功后的跳转地址就在第二个字段。如果没有匹配,则认为为普通指令。

同时,我们也可以结合前两种方法,在分支目标缓冲器中增设一个至少是两位的分支历史表的字段,具体操作如下图所示:
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第29张图片
【计算机系统结构】 【北邮】第五章 指令并行及其开发——硬件方法 上_第30张图片
下一篇文章介绍前瞻执行、多指令流出、超流水线处理机等知识。

你可能感兴趣的:(计算机系统结构,数据结构,开发语言,硬件架构,c语言)