4.2 指令的动态调度

59
161 4.2 指指指指指指指 静静静静 静静静静静静静静静 静静静静静 :, 静静静静静静静静 静静静静静静静静静静 静静静静静静静静静 静静静静静静静静静 ,, 静静静静静静静静 静静静静 静静静静静静静静静静静静静静静静 :, 静静静静静静静静静静静静静静静 静静静静 静静静静静静静静静静静静静静静静静指指指 指指指指指

description

第四章 指令级并行. 4.2 指令的动态调度. 静态调度 :在出现数据相关时,为了消除或 者减少流水线空转,编译器确定并分离出程 序中存在相关的指令,然后进行指令调度, 并对代码进行优化。 动态调度 :通过硬件重新安排指令的执行顺序, 来调整相关指令实际执行时的关系,减少处理 器空转。 以硬件复杂性的显著增加为代价。. 4.2 指令的动态调度. 4.2.1 动态调度的原理. 到目前为止我们所使用流水线的最大的 局限性 : 指令必须顺序流出 看下面一段代码: DIVD F0 , F2 , F4; S1 - PowerPoint PPT Presentation

Transcript of 4.2 指令的动态调度

Page 1: 4.2 指令的动态调度

1/ 61

4.2 指令的动态调度

静态调度:在出现数据相关时,为了消除或 者减少流水线空转,编译器确定并分离出程

序中存在相关的指令,然后进行指令调度, 并对代码进行优化。

动态调度:通过硬件重新安排指令的执行顺序,

来调整相关指令实际执行时的关系,减少处理 器空转。

以硬件复杂性的显著增加为代价。

第四章 指令级并行

Page 2: 4.2 指令的动态调度

2/ 61

4.2.1 动态调度的原理

到目前为止我们所使用流水线的最大的局限性 : 指令必须顺序流出看下面一段代码: DIVD F0 , F2 , F4 ; S1 ADDD F10 , F0 , F8 ; S2 : S2 对 S1 数据相关 , S2 被阻塞 SUBD F12 , F8 ,F14 ;S3 : S3 与 S1 、 S2

都没 有相关 ,但也被阻塞

4.2 指令的动态调度

Page 3: 4.2 指令的动态调度

3/ 61

为了允许乱序执行,我们将基本流水线的译码阶段 再分为两个阶段: (1) 流出( Issue , IS ):指令译码,检查是否存

在结构阻塞。 (2) 读操作数( Read Operands , RO ):当没有数

据相关引发的阻塞时就读操作数。 指令乱序结束带来的最大问题 : 异常处理比较复杂 ( 精确异常处理、不精确异常处理 )

4.2 指令的动态调度

Page 4: 4.2 指令的动态调度

4/ 61

4.2.2 动态调度算法之一:记分牌 例:数据先读后写( WAR )相关引起的阻塞 代码序列: DIVD F0 , F2 , F4

ADDD F10 , F0 , F8

SUBD F8 , F8 , F14

指令乱序执行时就会出现先读后写相关。 记分牌技术的目标: 在资源充足时,尽可能早地执行没有数据阻 塞的指令,达到每个时钟周期执行一条指令。

4.2 指令的动态调度

Page 5: 4.2 指令的动态调度

5/ 61

要发挥指令乱序执行的好处,必须有多条指令 同时处于执行阶段,这就要求有多个功能部件 或功能部件流水化或者两者兼有。

假设:处理器采用多个功能部件。 CDC 6600 具有 16 个功能部件: 4 个浮点部件,

5 个存储器访问部件 7 个整数操作部件 在 DLX 中,假设有 2个乘法器、 1个加法器、

1 个除法部件和 1个整数部件。

4.2 指令的动态调度

Page 6: 4.2 指令的动态调度

1. 采用记分牌技术的 DLX 处理器的基本结构。 寄存器

整数部件

记分牌

浮点除法

浮点乘法

浮点乘法

数据总线

控制/状态 控制/状态

浮点加法

图 4.1 具有记分牌的 DLX 处理器基本结构

Page 7: 4.2 指令的动态调度

7/ 61

记分牌电路负责记录资源的使用,并负责相关检测,控制指令的流出和执行。

2. 每条指令在流水线中的执行过程分为四段: (1) 流出( Issue ,记为 IS) 如果本指令所需的功能部件有空闲,并 且其它正在执行的指令使用的目的寄存器与 本指令的不同,记分牌就向功能部件流出本 指令,并修改记分牌内部的数据记录。 解决了指令间存在的结构相关或写后写相关。

4.2 指令的动态调度

Page 8: 4.2 指令的动态调度

8/ 61

(2) 读操作数( Read Operand ,记为 RO)。 记分牌需要监测源操作数寄存器中数据的 有效性,如果前面已流出的还在运行的指令不 对本指令的源操作数寄存器进行写操作,或者 一个正在工作的功能部件已经完成了对这个寄 存器的写操作,那么此操作数有效。当操作数 有效后,记分牌将启动本指令的功能部件读操 作数并开始执行。 解决了数据的先写后读( RAW )相关。 通过以上步骤,记分牌动态解决了结构相 和数据相关引发的阻塞,指令可能乱序流出。

4.2 指令的动态调度

Page 9: 4.2 指令的动态调度

9/ 61

(3) 执行( Execution ,记为 EX )。(4) 写结果( Write Result,记为 WR)。 记分牌知道指令执行完毕后,如果目标 寄存器空闲,就将结果写入到目标寄存器中, 然后释放本指令使用的所有资源。 检测先读后写( WAR )相关 在出现以下的情况时,就不允许指令写结果 :• 前面的某条指令(按顺序流出)还没有读取操作数;• 其中某个源操作数寄存器与本指令的目的寄存器相同。

4.2 指令的动态调度

Page 10: 4.2 指令的动态调度

10/ 61

存在一个问题 :就是功能部件到寄存器文件的数据总线宽度是有限的,当流水线中进入读操作数段( RO)和写结果段( WB)的功能部件总

数超过可用总线的数目,这会导致结构阻塞。

3. 记分牌需要纪录的信息分为三部分: (1) 指令状态表 记录正在执行的各条指令已经进入记 分牌 DLX 流水线四段中的哪一段。

4.2 指令的动态调度

Page 11: 4.2 指令的动态调度

11/ 61

(2) 功能部件状态表 纪录各个功能部件的状态。每个功能部件 在状态表中都由以下九个域来纪录: Busy: 指示功能部件是否在工作 Op : 功能部件当前执行的操作 Fi: 目的寄存器编号 Fj, fk:源寄存器编号 Qj, Qk:向 Rj, Rk中写结果的功能部件 Rj, Rk:表示 Fj, Fk是否就绪, 是否已经被使用

4.2 指令的动态调度

Page 12: 4.2 指令的动态调度

12/ 61

(3) 结果寄存器状态表 每个寄存器在表中有一个域,用于纪录写 入本寄存器的功能部件(编号)。如果当前正 在运行的功能部件没有需要写入本寄存器的, 则相应域置为空。4. DLX 记分牌所要维护的数据结构 给出下列代码运行过程中记分牌保存的信息 .

4.2 指令的动态调度

Page 13: 4.2 指令的动态调度

13/ 61

LD F6 , 34(R2)

LD F2 , 45(R3)

MULTD F0 , F2 , F4

SUBD F8 , F6 , F2

DIVD F10 , F0 , F6

ADDD F6 , F8 , F2

4.2 指令的动态调度

Page 14: 4.2 指令的动态调度

14/ 61

指 令 指令状态表 IS RO EX WR

LD F6 , 34(R2) √ √ √ √

LD F2 , 45(R3) √ √ √

MULTD F0 , F2 , F4 √

SUBD F8 , F6 , F2 √

DIVDF10 , F0 , F6 √

ADDD F6 , F8 , F2

图 4.2 DLX 记分牌信息组成和记录的信息

4.2 指令的动态调度

Page 15: 4.2 指令的动态调度

部件名称 功能部件状态表

Busy Op Fi Fj Fk Qj Qk Rj Rk整数 yes LD F2 R3 no

乘法 1 yes MULTD F0 F2 F4 整数 no yes

乘法 2 no

加法 yes SUBD F8 F6 F2 整数 yes no

除法 yes DIVD F10 F0 F6 乘法 1 no yes

结果寄存器状态表

F0 F2 F4 F6 F8 F10 … F30

部件名称 乘法 1 整数  加法 除法

Page 16: 4.2 指令的动态调度

16/ 61

例 4.3 假设浮点流水线中执行的延迟如下: 加法需 2个时钟周期 乘法需 10个时钟周期 除法需 40个时钟周期 代码段和记分牌信息的起始点状态如图 4.2 。分别给出 MULTD 和 DIVD准备写结果之前的记分牌状态。

解: 在分析记分牌状态之前,首先需要分析指令之间存在的相关性,因为相关性会影响指令进入记分牌 DLX 流水线的相应段。

4.2 指令的动态调度

Page 17: 4.2 指令的动态调度

17/ 61

(1) 第二个 LD指令到 MULD 和 SUBD 、 MULTD 到 DIVD 之间以及 SUBD 到 ADDD之间存在着先写后读相关;(2) DIVD 和 ADDD之间存在着先读后写相关;(3) ADDD 和 SUBD 指令关于浮点加法部件还存在着结 构相关。 图 4.3 和图 4.4 分别给出了 MULTD 指令和 D

IVD 指令将要写结果时记分牌的状态。

4.2 指令的动态调度

Page 18: 4.2 指令的动态调度

18/ 61

指 令 指令状态表 IS RO EX WR

LD F6 , 34(R2) √ √ √ √

LD F2 , 45(R3) √ √ √ √

MULTD F0 , F2 , F4 √ √ √

SUBD F8 , F6 , F2 √ √ √ √

DIVDF10 , F0 , F6 √

ADDD F6 , F8 , F2 √ √ √

图 4.3 程序段执行到 MULTD 将要写结果时记分牌的状态

4.2 指令的动态调度

Page 19: 4.2 指令的动态调度

部件名称 功能部件状态表

Busy Op Fi Fj Fk Qj Qk Rj Rk整数 no

乘法 1 yes MULTD F0 F2 F4 no no

乘法 2 no

加法 yes ADDD F6 F8 F2 no no

除法 yes DIVD F10 F0 F6 乘法 1 no yes

结果寄存器状态表

F0 F2 F4 F6 F8 F10 … F30

部件名称 乘法 1 加法 除法

Page 20: 4.2 指令的动态调度

20/ 61

指 令 指令状态表 IS RO EX WR

LD F6 , 34(R2) √ √ √ √

LD F2 , 45(R3) √ √ √ √

MULTD F0 , F2 , F4 √ √ √ √

SUBD F8 , F6 , F2 √ √ √ √

DIVD F10 , F0 , F6 √ √ √

ADDD F6 , F8 , F2 √ √ √ √

图 4.4 程序段执行到 DIVD 将要写结果时记分牌的状态

4.2 指令的动态调度

Page 21: 4.2 指令的动态调度

部件名称 功能部件状态表

Busy Op Fi Fj Fk Qj Qk Rj Rk整数 no

乘法 1 no

乘法 2 no

加法 no

除法 yes DIVD F10 F0 F6 no no

结果寄存器状态表

F0 F2 F4 F6 F8 F10 … F30

部件名称   除法

Page 22: 4.2 指令的动态调度

22/ 61

5. 分析记分牌是如何控制指令执行的。 操作在记分牌流水线中前进时,记分牌必须 记录与操作有关的信息,如寄存器号等。 约定: Fj( FU)‘ S1’ :将寄存器 S1 的名字送入Fj( FU)

FU : 指令使用的功能部件 D : 目的寄存器的名字 S1 和 S2 : 源操作数寄存器的名字, Op : 进行的操作 Fj( FU): 功能部件 FU的 Fj 域 result( D):结果寄存器状态表中对应于寄存

器D的内容,为产生寄存器 D中结果的功能部件名。

4.2 指令的动态调度

Page 23: 4.2 指令的动态调度

23/ 61

流出( IS) (1) 进入条件 not Busy(FU) and not result(’D’); // 判断结构阻塞和写后写 (2) 计分牌记录内容 Busy(FU)←yes; OP(FU)←Op ; Fi(FU)←’D’ ; Fj(FU)←’S1’ ; Fk(FU)←’S2’;

4.2 指令的动态调度

Page 24: 4.2 指令的动态调度

24/ 61

Qj←result(’S1’); //处理’ S1’的 FU Qk←result(’S2’); //处理’ S2’的 FU Rj←not Qj ; //Rj是否可用? Rk←not Qk ; //Rk是否可用? result(’D’)←FU; //’D’被 FU用

作目的寄存器 读操作数( RO) (1) 进入条件 Rj·Rk; //解决先写后读,两个源操作数须同时就绪

4.2 指令的动态调度

Page 25: 4.2 指令的动态调度

25/ 61

(2)计分牌记录内容 Rj←no ; //已经读走了就绪的数据 Rj Rk←no ; //已经读走了就绪的数据 Rk Qj←0; //不再等待其它 FU的计算结果 Qk←0; 执行( EX ) (1) 结束条件 功能部件操作结束

4.2 指令的动态调度

Page 26: 4.2 指令的动态调度

26/ 61

写结果( WR) (1) 进入条件 f((Fj(f)Fi(FU) or Rj(f)=no) and (Fk(f)Fi(FU) or Rk(f)=no)); //检查是否存在先读后写 (2)计分牌记录内容 f(if Qj(f)=FU then Rj(f)←yes); //有等结果的指令,则数据可用 f(if Qk(f)=FU then Rk(f)←yes); result(Fi(FU))←0; //没有 FU使用寄存器 Fi为目的寄存器 busy(FU)=no // 释放 FU

4.2 指令的动态调度

Page 27: 4.2 指令的动态调度

27/ 61

6. 记分牌的性能受限于以下几个方面: (1) 程序指令中可开发的并行性,即是否存在 可以并行执行的不相关的指令。 (2) 记分牌容量。记分牌的容量决定了流水线 能在多大范围内寻找不相关指令。 流水线中可以同时容纳的指令数量又 称为指令窗口。 (3) 功能部件的数目和种类。功能部件的总数 决定了结构冲突的严重程度。 (4) 反相关和输出相关。引起计分牌中先读后 写和写后写阻塞。

4.2 指令的动态调度

Page 28: 4.2 指令的动态调度

28/ 61

4.2.3 动态调度算法之二: Tomasulo 算法 Tomasulo 算法将记分牌的关键部分和寄存器换名 技术结合在一起。 基本核心:通过寄存器换名来消除写后写和先读

后写相关而可能引发的流水线阻塞。 下面的讨论是基于 DLX 的浮点流水线功能部件。 Tomasulo 算法中,寄存器换名是通过保留站来实

现,它保存等待流出和正在流出指令所需要的操 作数。

Tomasulo 算法的基本思想

4.2 指令的动态调度

Page 29: 4.2 指令的动态调度

29/ 61

•只要操作数有效,就将其取到保留站,避免指令流出时才到寄存器中取数据。

• 指令的执行结果直接送到等待数据的其它保留站中去。

• 一条指令流出时,存放操作数的寄存器名被换成为对应于该寄存器保留站的名称。

除了寄存器换名技术, Tomasulo 算法和记分牌在 结构上还有两处显著的不同:

4.2 指令的动态调度

Page 30: 4.2 指令的动态调度

30/ 61

• 冲突检测和指令执行控制机制分开。

• 计算的结果通过相关专用通路直接从功能部件 进入对应的保留站进行缓冲,而不一定是写到 寄存器。 (相关专用通路通过一条数据总线来实现)

4.2 指令的动态调度

Page 31: 4.2 指令的动态调度

指 令 队 列

3 2 1

2 1

浮点寄存器组 1 2 3 4

浮点加法器 浮点乘法器

公共数据总线(CDB)

存的数据

从指令部件来

保留站

存储器部件

取缓冲 6 5 4 3 2 1

地址部件

地址

取的数据

存-取操作 浮点操作

操作数总线

操作总线 存缓冲

1. 采用 Tomasulo 算法的 DLX 浮点部件的基本结构

Page 32: 4.2 指令的动态调度

32/ 61

保留站中保存已流出并等待到本功能部件执行的 操作(指令);还保存指令执行所需的控制信息。 •如果该操作的源操作数在寄存器中已经就绪,

刚将该操作数取来,保存到保留站中;•如果操作数还没有计算出来,则保留站中记

录这个操作数将由谁计算出来,即指明它由哪个功能部件产生。

取缓冲和存缓冲保存的是读 /写存储器的数据或 地址。

4.2 指令的动态调度

Page 33: 4.2 指令的动态调度

33/ 61

浮点寄存器通过一对操作数总线连到功能部件,通过其中一条总线连到公共数据总线,再送到存缓冲。

功能部件的计算结果和从存储器读取的数据都送到公用数据总线上,除了取缓冲的输入和存缓冲的输出以外,所有部分均与公用数据总线相连。

两个运算功能部件

• 浮点乘法器完成乘法和除法操作

• 浮点加法器完成加法和减法操作

4.2 指令的动态调度

Page 34: 4.2 指令的动态调度

34/ 61

2. 指令流水线的分段情况 使用 Tomasulo 算法的流水线需三段: (1) 流出( Issue ):从浮点操作队列中取一条指令。 (2) 执行( Execute ) (3) 写结果( Write Result) 3. 这些步骤和记分牌基本上类似,但有以下以下几点

不同: (1)无需任何操作来检查数据写后写和先读后写相关

的过程,在指令流出过程中操作数寄存器换名已 将其消除。

4.2 指令的动态调度

Page 35: 4.2 指令的动态调度

35/ 61

(2) 通过公共数据总线来广播结果,将结果送到 等待此结果作为操作数的保留站,目标寄存器也

相当于一个需要结果的保留站,而不是将结果 写回到寄存器中。

(3) 存储器存和取都作为基本的功能部件。(4)由于保留站技术能够有效地解决先写后读,而 无需特殊处理,因此,记分牌流水线中用于完 成判断先写后读的“取操作数”段也被消掉。

4.2 指令的动态调度

Page 36: 4.2 指令的动态调度

36/ 61

4. 定义有关的术语和数据结构 标志( tags )

指缓冲或产生结果的保留站(功能部件)。 每个保留站有以下 6个域:

Op :对源操作数 S1和 S2 所进行的操作。 Qj, Qk:产生结果的保留站号。等于 0表示

操作数在 Vj和 Vk中或不需要操作数。 Vj, Vk:两个源操作数的值。操作数项中, V或 Q 域最多只有一个有效。 Busy:标示本保留站和相应的功能部件是否空

闲。

4.2 指令的动态调度

Page 37: 4.2 指令的动态调度

37/ 61

每个寄存器和存缓冲有 1个 Qi 域:结果要存入本寄存 器或存缓冲的保留站号。 如果 Qi空,表示当前没有指令要将结果写入此 寄存器或存缓冲。 当寄存器空闲时, Qi 域空。 存缓冲和取缓冲还各有 1个 Busy 域和 1个 Address域 Busy:标示缓冲是否空闲。 A :地址域,用于记录存或取的存储器地址。

存缓冲还有 1个 V 域:保存要存入存储器的数据。

4.2 指令的动态调度

Page 38: 4.2 指令的动态调度

38/ 61

5. 对于下列代码,保留站的信息:

LD F6 , 34(R2)

LD F2 , 45(R3)

MULTD F0 , F2 , F4

SUBD F8 , F2 , F6

DIVD F10 , F0 , F6

ADDD F6 , F8 , F2

4.2 指令的动态调度

Page 39: 4.2 指令的动态调度

39/ 61

图 4.6 给出的是采用 Tomasulo 算法时保留站、存缓冲、

取缓冲和寄存器的标志等信息。 指 令 指令状态表

流出 执行 写结果

LD F6 , 34(R2) √ √ √

LD F2 , 45(R3) √ √

MULTD F0 , F2 , F4 √

SUBD F8 , F6 , F2 √

DIVDF10 , F0 , F6 √

ADDD F6 , F8 , F2 √

4.2 指令的动态调度

Page 40: 4.2 指令的动态调度

名称 保留站

Load1

Load2

Add1

Add2

Add3

Mult1

Mult2

Busy

no

yes

yes

yes

no

yes

yes

Op

 

LD

SUBD

ADDD

 

MULTD

DIVD

Vj Vk MEM[34+REGS[R2]] REG[F4] MEM[34+REGS[R2]]

Qj Load2 Add1 Load2 Mult1

Qk Load2

A 45+Regs[R3]

寄存器状态表

F0 F2 F4 F6 F8 F10 … F30

Qi Mult1 Load2 Add2 Add1 Mult2 …

Page 41: 4.2 指令的动态调度

41/ 61

6.Tomasulo 算法相对于记分牌技术主要的优点: (1) 具有分布的阻塞检测机制; (2) 消除了数据的写后写和先读后写相关导致的

阻塞。 例 4.4 假设浮点部件的延迟为: 加法 2个时钟周期, 乘法 10 个时钟周期, 除法 40 个时钟周期。 执行的代码同上,给出 MULTD 准备写结

果时的状态表的信息。 解 结果如图 4.7 所示。

4.2 指令的动态调度

Page 42: 4.2 指令的动态调度

42/ 61

指 令 指令状态表 流出 执行 写结果

LD F6 , 34(R2) √ √ √

LD F2 , 45(R3) √ √ √

MULTD F0 , F2 , F4 √ √

SUBD F8 , F6 , F2 √ √ √

DIVD F10 , F0 , F6 √

ADDD F6 , F8 , F2 √ √ √

4.2 指令的动态调度

Page 43: 4.2 指令的动态调度

名称 保留站

Load1

Load2

Add1

Add2

Add3

Mult1

Mult2

Busy

no

yes

yes

yes

no

yes

yes

Op

MultD DIVD

Vj

MEM[45+REGS[R3]]

Vk REG[F4] MEM[34+REGS[R2]]

Qj Mult1

Qk

A

 

寄存器状态表

F0 F2 F4 F6 F8 F10 … F30

Qi Mult1 Mult2 …

Page 44: 4.2 指令的动态调度

44/ 61

7. Tomasulo 算法中指令执行的主要条件、步骤和记录 其中: rd :目的寄存器 rs 和 rt:操作数寄存器号 imm:符号扩展的立即数 r :分配给相应指令的保留站或者缓冲 RS :保留站数据结构,由保留站或取缓冲返

回的值为 result。 RegisterStat:寄存器状态的数据结构

(寄存器文件用 Regs[ ] 表示)

4.2 指令的动态调度

Page 45: 4.2 指令的动态调度

45/ 61

指令流出( Issue ) (1) 进入条件 ① 对于浮点操作:有空闲保留站 r ② 对于取 /存操作:有空闲缓冲 r(2) 记录内容 ① 对于浮点操作: if (RegisterStat[rs].Qi 0) // 第一操作数 RS[r].Qj RegisterStat[rs].Qi

// 操作数寄存器 rs 未就绪,进行寄存器换名 else RS[r].Vj Reg[rs]; // 把寄存器 rs 中的操作数取到保留站 RS[r].Qj 0; //数据 Vj有效

4.2 指令的动态调度

Page 46: 4.2 指令的动态调度

46/ 61

if (RegisterStat[rt].Qi 0) // 第二操作数 RS[r].Qj RegisterStat[rt].Qi

// 操作数寄存器 rt 未就绪,进行寄存器换名else RS[r].Vk Reg[rt];

// 把寄存器 rs 中的操作数取到保留站 RS[r].Qk 0; // 数据 Vk 有效RS[r].Busy yes ; // 本保留站忙RS[r].Op Op ; // 设置本保留站的操作类型 RegisterStat[rd].Qi r ;

// 寄存器 rd 是本指令的目标寄存器

4.2 指令的动态调度

Page 47: 4.2 指令的动态调度

47/ 61

② 对于存 / 取操作: if (RegisterStat[rs].Qi 0) RS[r].Qj RegisterStat[rs].Qi

// 操作数寄存器 rs 未就绪,进行寄存器换名else RS[r].Vj Reg[rs];

// 把寄存器 rs 中的操作数取到保留站 RS[r].Qj 0; // 数据 Vj 有效RS[r].Busy yes ; // 本保留站忙RS[r].A Imm ; // 设置本保留站的操作类型

4.2 指令的动态调度

Page 48: 4.2 指令的动态调度

48/ 61

③ 对于取操作: RegisterStat[rd].Qi r ;

// 寄存器 rd 是本指令的目标寄存器

④ 对于存操作: if (RegisterStat[rt].Qi 0) RS[r].Qk RegisterStat[rt].Qi

// 操作数寄存器 rt 未就绪,进行寄存器换名 else RS[r].Vk Reg[rt];

// 把寄存器 rt 中的操作数取到存缓冲 RS[r].Qk 0; // 数据 Vk 有效

4.2 指令的动态调度

Page 49: 4.2 指令的动态调度

49/ 61

执行( Execution ) (1) 进入条件 ① 对于浮点操作: (RS[r].Qj = 0) and (RS[r].Qk = 0);

//两个源操作数就绪 ② 对于取 /存操作第 1步: (RS[r].Qj = 0) and (r 到达取 /存缓冲队列的头部 ) ③ 对于取操作第 2步: 取操作第 1步执行结束

4.2 指令的动态调度

Page 50: 4.2 指令的动态调度

50/ 61

( 2)记录内容 ① 对于浮点操作:产生计算结果 ② 对于取 /存操作第 1步: RS[r].A RS[r].Vj + RS[r].A;

// 计算有效地址 ③ 对于取操作第 2步: 读 取 数 据 Mem[RS[r].A];

// 从存储器中读取数据

4.2 指令的动态调度

Page 51: 4.2 指令的动态调度

51/ 61

写结果( Write Result) ( 1)进入条件 ① 对于浮点操作或取操作: 保留站 r 执行结束,且公共数据总线

( CDB)可用(空闲) ② 对于存操作: 保留站 r 执行结束,且 RS[r].Rk = 0

//存的数据已经就绪 ( 2)记录内容 ① 对于浮点操作或取操作:

4.2 指令的动态调度

Page 52: 4.2 指令的动态调度

52/ 61

x (if(RegisterStat[x].Qi = r)fx result;

//向浮点寄存器写结果(所有的 fx)RegisterStat[x].Qi 0;

//相应的目标寄存器中结果有效x (if(RS[x].Qj = r)RS[x].Vj result;

//使用本结果作为第一操作数的保留站RS[x].Qj 0); //相应的操作数有效

4.2 指令的动态调度

Page 53: 4.2 指令的动态调度

53/ 61

x (if(RS[x].Qk = r)RS[x].Vk result; //使用本结果作为第二操作数的保留站RS[x].Qk 0);

//相应的操作数有效RS[r].Busy no;

// 释放保留站 , 置保留站空闲② 对于存操作:Mem[RS[r].A] RS[r].Vk //数据送存储器 RS[r].Busy no; // 释放保留站 , 置保留站空

4.2 指令的动态调度

Page 54: 4.2 指令的动态调度

54/ 61

例 4.5 :一个将数组中的元素与 F2 中的标量相乘的代码: Loop : LD F0,0(R1)

MULTD F4,F0,F2 SD 0(R1),F4 SUBI R1,R1,#8 BNEZ R1,Loop

现在假设将连续两遍循环的所有指令全都流出,但所有的浮点存、取及运算操作全都没完成。给出状态表的信息。

4.2 指令的动态调度

Page 55: 4.2 指令的动态调度

55/ 61

解:保留站、寄存器状态表以及此时的存取缓冲 如图 4.8所示。 忽略整数部件 ALU的操作,假设转移成功,乘法操作可在 4个时钟周期内完成,一旦系统达到此状态则两遍循环同时执行, CPI 将达到接近 1.0 。如果忽略循环的开销,且有足够的寄存器,那么性能可达到通过编译器循环展开并调度后的水平。

4.2 指令的动态调度

Page 56: 4.2 指令的动态调度

56/ 61

指 令 指令状态表 循环遍次 流出 执行 写结果

LD F0 , 0(R1) 1 √ √

MULTD F4 , F0 , F2 1 √

SD 0(R1) , F4 1 √

LD F0 , 0(R1) 2 √ √

MULTD F4 , F0 , F2 2 √

SD 0(R1) , F4 2 √

4.2 指令的动态调度

Page 57: 4.2 指令的动态调度

寄存器状态表

F0 F2 F4 F6 F8 F10 … F30

Qi Load2 Mult2 …

名称 保留站

Load1

Load2

Add1

Add2

Add3

Mult1

Mult2

Store1

store2

Busy

yes

yes

no

no

no

yes

yes

yes

yes

Op LD LD MULTD MULTD SD SD

Vj

Regs[R1]

Regs[R1]-8

Vk

Regs[F2]Regs[F2]

Qj Load1 Load2

Qk

Mult1Mult2

ARegs[R1]Regs[R1]-8

Page 58: 4.2 指令的动态调度

58/ 61

在此例中有 Tomasulo 算法的另一个关键技术: 动态存储器地址判别

如果分支操作的开销不大, Tomasulo 算法的动态调度机制能得到非常高的性能。这种方法的主要缺点是 Tomasulo 算法实现的复杂性,实现它需要大量的硬件,尤其是保存大量相关中间结果的高速缓冲寄存器和复杂的控制逻辑。此外,性能还受限于公共数据总线,因为它是单总线,如果增加公共数据总线的数量,与总线连接的缓冲和保留站的接口硬件将会加倍。

4.2 指令的动态调度

Page 59: 4.2 指令的动态调度

59/ 61

8.Tomasulo 算法结合了两种不同的技术: ( 1)寄存器换名

可以获得一个更大的虚拟寄存器空间。 ( 2)对寄存文件中源操作数缓存

解决了寄存器中的有效操作数相关引起的阻塞。Tomasulo 算法提高指令级并行的关键技术是:

• 指令动态调度

• 寄存器换名

• 动态存储器地址判别

4.2 指令的动态调度