一、前言
代码大部分来自该网址。本文章主要是对算法进行分析,同时根据该网址的代码进行具体实现的讲解。
该网址中的代码我找到了三处bug:
1、输入指令中最后一条指令无法读入。
是个小bug,很容易修。
2、输入指令的数据相关未处理好。
举例如下:
ADD F0 F1 F2
MULT F3 +45 F0
SUBD F6 F3 F0
MULT由于F0被ADD阻塞,SUBD由于F3和F0被MULT和ADD阻塞,上述网址中的算法无法针对这种情况给出正确的流水顺序,实际上表现为直接卡死。需要修改判断逻辑。
3、在同一周期有多条指令写回完毕时,无法处理多条指令。
是个不大不小的bug,修改返回值就能解决。
我将该应用部署在了我的服务器上,可以尝试访问该网址去使用。
testcase如下:
LD F6 34+ R2
LD F2 45+ R3
MULT F0 F2 F4
SUBD F8 F6 F2
DIVD F10 F0 F6
ADDD F6 F8 F2
LD F6 34+ R2
LD F2 45+ R3
MULT F0 F2 F4
SUBD F8 F6 F2
SUBD F6 F8 F0
DIVD F10 F0 F6
ADDD F6 F8 F2
LD F6 34+ R2
LD F2 45+ R3
MULT F0 F2 F4
SUBD F8 F6 F2
MULT F10 F0 F8
ADDD F0 F10 F6
SUBD F6 F8 F0
DIVD F10 F0 F6
ADDD F6 F8 F2
LD F0 12+ R1
SUBD F9 F10 F0
若出现500错误,说明我的小服务器不堪重负,请清理浏览器缓存+重启浏览器再次访问即可。
二、记分牌调度算法分析
1、概述
记分牌调度算法用于实现指令流水线的乱序输出,解决部分数据相关问题。它维护三个数据结构:
Instruction Status:保存输入指令流的各个属性,记录其流水状态。
Function Unit Status:保存CPU中各功能部件的状态。
Register Result Status:保存寄存器的使用状态。
通过这三张表的配合,实现指令的乱序执行。
2、数据结构
如下为Instruction Status:
Instruction | J | K | Issue | Read Operand | Execution Complete | Write Result | Target |
其各列含义如下:
Instruction:输入的指令名称,如ADD、SUBD、LD什么的;
J、K:源寄存器,如F3、F4等;
Issue、Read Operand、Execution Complete、Write Result:指令执行的四个步骤,内容为该步骤执行完毕的周期。具体如下:
Issue:该阶段对Function Unit Status进行初始化,具体步骤见后文;
Read Operand:该阶段从源寄存器取数;
Execution Complete:该阶段表示指令执行完毕,释放功能部件的资源;
Write Result:该阶段将数据写入目标寄存器;
Target:目标寄存器,如F3,F4等。
如下为Function Unit Status,Function Unit Status仅与CPU的硬件结构有关系,因此可以直接将其初始化:
Name | Busy | Op | Fi | Fj | Fk | Qj | Qk | Rj | Rk |
Integer | |||||||||
Mult1 | |||||||||
Mult2 | |||||||||
Add | |||||||||
Divide |
其各列含义如下:
Name:功能部件名称,如Integer、Add、Divide等;
Busy:该部件是否忙绿,取值Yes或No;
Op:该部件执行什么操作,这和Name在某些指令上重复,在某些指令上不重复,比如ADD和SUBD都是用Add部件实现的;
Fi、Fj、Fk:源寄存器和目标寄存器名称;
Qj、Qk:占据源寄存器的指令名,若Rj、Rk为No,则该处有值,其值为向该寄存器写入值的指令名;
Rj、Rk:指示源寄存器是否被占据,取值Yes或No。
如下为Register Result Status:
F0 | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 |
其各列为目标寄存器名称,保存目前占据该寄存器的功能部件名。
3、分析
在算法开始之前,首先要读入所有指令,在所有指令读入的过程中,对Instruction Status进行初始化:
我们以前言中所述的第一个testcase为例进行初始化:
Instruction | J | K | Issue | Read Operand | Execution Complete | Write Result | Target |
LD | F6 | ||||||
LD | F2 | ||||||
MULT | F2 | F4 | F0 | ||||
SUBD | F6 | F2 | F8 | ||||
DIVD | F0 | F6 |