体系结构实验(3)—— 指令流水的分析

Chp3 Lab: Analysis of Instruction Execution Pipelining

Using the following code fragment:

LOOP: LW R1,0(R2) ; load R1 from address 0+R2
ADDI R1,R1,#1 ; R1=R1+1
SW 0(R2),R1; store R1 at address 0+R2
ADDI R2,R2,#4; R2=R2+4
SUB R4,R3,R2; R4=R3-R2
BNEZ R4,Loop ; branch to loop if R4!=0
Assume that the initial value of R3 is R2+396.

Analyze (a) by showing the timing of the first two iterations and calculate the total cycles needed; implement (b) and © in WinMIPS64. Execute the code in MARS, describe the difference between WinMIPS64 and MARS.

分析(a)通过显示前两个迭代的时间,并计算所需的总周期;实现(b)和©在WinMIPS64。在MARS中执行代码,描述WinMIPS64和MARS的区别。

a.

(a) Show the timing of this instruction sequence for the RISC pipeline without any forwarding or bypassing hardware but assuming a register read and a write in the same clock cycle “forwards” through the register file. Assume that the branch is handled by flushing the pipeline. If all memory references take 1 cycle, how many cycles does this loop take to execute?

在没有任何转发或绕过硬件的情况下,显示这个指令序列在RISC流水线上的计时,但假设在相同的时钟周期内,通过寄存器文件“转发”读和写寄存器。假设通过冲洗管道来处理分支。如果所有内存引用都需要一个周期,那么执行这个循环需要多少个周期?

在上述的代码中由于数据的依赖关系会发生Data hazards。首先列出存在依赖关系的指令(分别表示源指令和目标指令)和寄存器。

  • 第一条ADDI指令必须等到上一条LW指令执行完写回的阶段才能够得到正确的R1的值。
  • SW指令必须等到第一条ADDI指令计算完R1的值执行完写回阶段时才能开始执行。
  • SUB指令要等到第二条ADDI指令计算完R2的值到达写回阶段时才能开始执行。
  • BNEZ必须要等到SUB指令计算完R4的值到达写回阶段时才能开始执行。
  • LD指令在分支指令后需要重新的取值(当采用了分支跳转)

由于采用了通过寄存器文件“转发”读和写寄存器、冲洗管道来处理分支,目标和分支结果直到写回阶段结束后才知道。

1234567891011121314151617181920
LW R1,0(R2)FDXMW
ADDI R1,R1,#1FD--XMW
SW 0(R2),R1F--D--XMW
ADDI R2,R2,#4F--DXMW
SUB R4,R3,R2FD--XMW
BNEZ R4,LoopF--D--XMW
LW R1,0(R2)F--FDXMW

由于R3的初始值为R2+396, 并且在每次的循环过程中R2都会加上4。循环的条件是R4不等于0。由于R4=R3-R2, 即当R2=R3时结束循环。所以循环的总次数为396/4=99。。

在每一次循环的过程中,由于Read and Write hazards 以及 分支跳转指令会损失8个周期。其中分支指令会损失两个时间周期由于instruction flushing。

如上表所示,第i次循环中第一条指令的开始取指令的时钟周期为1+15*i, 而最后一次循环过程中需要18个时钟周期完成。因此总共需要的时钟周期为98*15+18=1488

b.

(b) Show the timing of this instruction sequence for the RISC pipeline with normal forwarding and bypassing hardware. Assume that the branch is handled by predicting it as not taken. If all memory references take 1 cycle, how many cycles does this loop take to execute?

显示这个指令序列的时间为RISC管道正常转发和旁路硬件。假设该分支是通过预测其未被采用来处理的。如果所有内存引用都需要一个周期,那么执行这个循环需要多少个周期?

WinMIPS64 上进行测试,在执行完第一次循环后statistics会出现2次RAW stall 和 1次branch taken stall。
在这里插入图片描述

由于我们现在使用了forwarding 和 bypassing hardware,分支结果和目标值在译码阶段结束后就可以知道了。

  • 第一个ADDI仍然必须等到LW到达WB阶段才能得到R1的值,但现在stall通过联锁机制在EX阶段实现,值直接转发到EX阶段。
  • SW会等待直到第一个ADDI计算出R1的值并从EX转发该值到MEM
  • SUB获得由第二个ADDI转发的R2值,而不需要等待。
  • BNEZ现在得到sub转发的R4的值,但需要等待sub到EXE阶段。
  • 当分支被解析为错误预测后,将重新获取下一次迭代的LW
1234567891011121314
LW R1,0(R2)FDXMW
ADDI R1,R1,#1FD-XMW
SW 0(R2),R1F-DXMW
ADDI R2,R2,#4FDXMW
SUB R4,R3,R2FDXMW
BNEZ R4,LoopFD-XMW
LW R1,0(R2)F-FDXMW

如上表所示,第i次循环中第一条指令的开始取指令的时钟周期为1+9*i, 而最后一次循环过程中需要12个时钟周期完成。因此总共需要的时钟周期为98*9+12=894

  • Mars模拟器和WinMIPS64模拟器的区别

然后在mars上编写具有相同功能的代码如下:

.text 
main:
addi $t2,$zero, 0x10010000
addi $t3,$t2,396
Loop: 
lw $t1,0($t2) 
addi $t1,$t1,1
sw $t1,0($t2)
addi $t2,$t2,4
sub $t4,$t3,$t2 
bnez $t4,Loop 
Finish:
 	li $v0, 10
	syscall
  1. 功能侧重不同

    首先Mars模拟器上的窗口是会显示代码区,调试区,数据段,寄存器段。但是WinMIPS64的窗口有Cycles 显示指令的执行的5段式流水线,pipeline 显示的是5段流水线的结构示意图。Registers 窗口显示的是寄存器以及具体的数值。Data 窗口显示的是数据段的内容和值。code 显示代码区,可以显示目前执行到哪一条语句。statistics 用来显示执行的指令个数、占用的指令周期数、不同原因导致stall的次数、以及代码的大小。Mars主要侧重于较为宏观的指令执行和调试,侧重于程序功能的实现;而WinMIP64把每一条指令的执行拆开了显示,会展示每条指令执行过程中的取指令、译码、执行指令、访存和写回5部分。侧重于分析指令的执行速度,而这些在Mars中对程序员是透明的。

  2. 寄存器不同

    WinMIP64是采用的寄存器有R0~R31以及F0~F31, 而Mars上的寄存器标号有$a0~$a3$t0~$t1s0~s7t8~t9等,因此代码的编写方面有所不同。

  3. 指令执行速度

    WinMIP64给出了CPI, 即每条指令占用的平均时钟周期,理论上指导了CPU的时钟周期后就可以计算出整个程序代码的执行时间。Mars模拟器上可以选择每秒钟执行的指令数,或者也可以选择以最大化的速度来运行,至于是如何调节执行的速度对于程序员来说是透明的。总的来说就是,mars可以执行速度的结果为导向倒推出不同的执行方式。而WinMIP64则是由不同的执行方式得到不同的执行速度,是一个正向推导的过程。

  4. 执行的方式

    在WinMIP64上可以选择不同的执行选项,如Enable ForwardingEnable Branch Target BufferEnable Delay Slot 这些选项,用来控制不同的执行方式。而在Mars上没有这些选择。

在这里插入图片描述

c.

© Assume the RISC pipeline with a single-cycle delayed branch and normal forwarding and bypassing hardware. Schedule the instructions in the loop including the branch delay slot. You may reorder instructions and modify the individual instruction operands, but do not undertake other loop transformations that change the number or opcode of the instructions in the loop. Show a pipeline timing diagram and compute the number of cycles needed to execute the entire loop.

假设RISC流水线具有单周期延迟分支和正常转发和旁路硬件。调度循环中的指令,包括分支延迟槽。您可以重新排序指令并修改单个指令操作数,但不进行其他改变循环中指令的数目或操作码的循环转换。显示管道计时图并计算执行整个循环所需的周期数。

优化方法:

  • 将第二个addi指令移动到加载延时的时隙中
  • sub指令向前移动到第二个addi之后
  • sw移动到分支等待的时隙,并调整偏移地址为(SW-4(R2),R1)

修改后的mips2.s代码如下所示:

    .text
    loop: LD R1,0(R2)
    DADDI R2,R2,4
    DSUB R4,R3,R2
    DADDI R1,R1,1
    BNEZ R4,loop
    SD -4(R2),R1

然后在WinMIPS64 上进行测试,指令的执行流水线结果如下图所示:

在这里插入图片描述

1234567891011
LW R1,0(R2)FDXMW
ADDI R2,R2,#4FDXMW
SUB R4,R3,R2FDXMW
ADDI R1,R1,#1FDXMW
BNEZ R4,LoopFDXMW
SW -4(R2),R1 FDXMW
LW R1,0(R2)FDXMW
  • 修改完成之后,首先指令ADDI R1,R1,#1 不需要额外等待,因为与第一个LW指令之间间隔了两个指令,刚好多占用了两个时钟周期
  • 其次BNEZ R4,Loop 指令也不需要额外的等待,因为它与sub指令也间隔了一条指令,即不需要多占用一个时钟周期。
  • 最后,SW指令占用了分支等待的时隙。使得第二次循环的第一条LW指令也不需要额外的等待时间。

如上表所示,第i次循环中第一条指令的开始取指令的时钟周期为1+6*i, 而最后一次循环过程中需要10个时钟周期完成。因此总共需要的时钟周期为6*98 +10=598

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zyw2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值