题目
其中:R3的初值是R2+396。假设:在整个代码序列的运行过程中,所有的存储器访问都是命中的,并且在一个时钟周期中对同一个寄存器的读操作和写操作可以通过寄存器文件“定向”。问:
(1)在没有任何其它定向(或旁路)硬件的支持下,请画出该指令序列执行的流水线时空图。假设采用排空流水线的策略处理分支指令,且所有的存储器访问都命中Cache,那么执行上述循环需要多少个时钟周期?
(2)假设该流水线有正常的定向路径,请画出该指令序列执行的流水线时空图。假设采用预测分支失败的策略处理分支指令,且所有的存储器访问都命中Cache,那么执行上述循环需要多少个时钟周期?
(3)假设该流水线有正常的定向路径和一个单周期延迟分支,请对该循环中的指令进行调度,你可以重新组织指令的顺序,也可以修改指令的操作数,但是注意不能增加指令的条数。请画出该指令序列执行的流水线时空图,并计算执行上述循环所需要的时钟周期数。
汇编代码解释
LW R1, 0(R2) ; 从地址 R2 偏移 0 处加载一个字到寄存器 R1
DADDIU R1, R1, #1 ; 将寄存器 R1 的值加上常数 1
SW R1, 0(R2) ; 将寄存器 R1 的值存储到地址 R2 偏移 0 处
DADDIU R2, R2, #4 ; 将寄存器 R2 的值加上常数 4,并将结果保存回寄存器 R2
DSUB R4, R3, R2 ; 将寄存器 R3 的值减去寄存器 R2 的值,并将结果保存到寄存器 R4 BNEZ R4, LOOP ; 如果寄存器 R4 不为零,则跳转到标签 LOOP 处继续执行
数据通路图示
第一问
寄存器读写可以定向,无其他旁路硬件支持,排空流水线
396/4 = 99
总的时钟周期数:(98×17)+18=1684
LW和DADDIU存在数据相关(R1),必须等LW将结果写回通用寄存器,才能进行ID读寄存器R1进行操作,第一条指令的WB阶段和第二条指令的ID阶段可以在同一个时钟周期内同时执行。
因为针对寄存器访问冲突,我们规定用时钟上升沿触发 Write,下降沿触发 Read,从而将这两类冲突完全分开。
其他存在数据相关的指令同理
Q:关于第i条指令的ID阶段和第i+1条指令的IF阶段在同一时钟周期执行
A:第i条指令的ID阶段执行完指令译码操作,第i+1条指令就可以通过PC从指令存储器读取指令放入IR覆盖掉原来的指令了。这样做的目的是为了尽可能充分地利用处理器资源,减少流水线的停顿时间,提高指令的执行效率。
排空流水线分支转移相关补充:
为了能够在每个时钟周期启动一条新的指令,流水线必须在IF段获得下一条指令的地址,并将其保存在PC中。但是,分支指令会改变PC的值,而且只有在Mem段结束时,这个新值才会被写入PC
第二问
有正常定向路径,预测分支失败。
定向技术:用于读后写相关情况
1.将计算结果从产生的地方(ALU出口)送到指令需要的地方(ALU入口)
2.从流水寄存器到功能部件入口(例如WB阶段的寄存器到ID阶段的寄存器)
LW R1, 0(R2) ; 从地址 R2 偏移 0 处加载一个字到寄存器 R1
DADDIU R1, R1, #1 ; 将寄存器 R1 的值加上常数 1
SW R1, 0(R2) ; 将寄存器 R1 的值存储到地址 R2 偏移 0 处
通过定向技术将LW中WB阶段更新后的R1值直接放入DADDIU中EX阶段的ALU入口,同时也可以放入SW中ID阶段供其读取(同上面的WB阶段与ID阶段的寄存器冲突)
预测分支失败:沿着失败路径处理指令(空操作),而实际分支是成功,第一次IF译码出来的是错的PC值,MEM分支转移后的才是正确的PC值 ,按分支目标地址重新获取指令执行
总的时钟周期数:(98×10)+11=991
第三问
有正常定向路径。单周期延迟分支。.
调整后的指令:
LOOP: LW R1, 0(R2) // 从地址R2处加载一个字到寄存器R1中
DADDIU R2, R2, #4 // 将R2的值递增4
DADDIU R1, R1, #1 // 将R1的值递增1
DSUB R4, R3, R2 // 计算R4 = R3 - R2
BNEZ R4, LOOP // 如果R4不等于零,则跳转到标签LOOP
SW R1, -4(R2) // 将R1的值存储到地址(R2-4)中
单周期指令延迟分支:
延迟槽的指令为:SW R1, -4(R2)
调度分支指令方法为从前调度(延迟槽中指令不影响程序),分支成功就接着循环重新执行一遍,不成功就是空操作,整个程序执行完成
总的时钟周期数:(98×6)+10=598