【计算机体系结构】实验4指令调度与分支延迟

指令调度与分支延迟

  • 实验目的
  • 实验平台
  • 实验内容和步骤
  • 实验分析和总结
    • Schedule.s
    • Branch.s
    • Array.s
  • 实验分析和总结:

实验目的

1.加深对指令调度技术的理解。
2.加深对分支延迟技术的理解。
3.熟练采用指令调度技术解决流水线中的数据冲突的方法。
4.进一步理解指令调度技术对 CPU 性能的改进。
5.进一步理解延迟分支技术对 CPU 性能的改进。

实验平台

实验平台采用指令级和流水线操作级模拟器 MIPSsim。

实验内容和步骤

1.启动 MIPSsim。

2.根据实验 3的相关知识中关于流水线各段操作的描述,进一步理解流水线窗口中各段的功能,掌握各流水线寄存器的含义(双击各段,就可以看到各流水线寄存器中的内容)。

3.选择“配置”→“流水方式”选项,使模拟器工作在流水方式下。

4.用指令调度技术解决流水线中的结构冲突与数据冲突:

  • 启动 MIPSsim。
  • 用 MIPSsim 的“文件”->“载入程序”选项来加schedule.s(在模拟器所在文件夹下的“样例程序”文件夹中)。
  • 关闭定向功能,这是通过“配置“->”定向“选项来实现的。
  • 执行所载入的程序,通过查看统计数据和时钟周期图,找出并记录程序执行过程中各种冲突发生的次数,发生冲突的指令组合以及程序执行的总时钟周期数。
  • 自己采用调度技术对程序进行指令调度,消除冲突(自己修改源程序)。将调度(修改)后的程序重新命名为 my-schedule.s。
  • 载入 my-schedule.s,执行该程序,观察程序在流水线中的执行情况,记录程序执行的总时钟周期数。
  • 比较调度前和调度后的性能,论述指令调度对提高 CPU 性能的作用。

5.用延迟分支技术减少分支指令对性能的影响:

  • 在MIPSsim中载入branch.s 样例程序(模拟器目录的“样例程序”文件夹中)。
  • 关闭延迟分支功能。这是通过在“配置”->“延迟槽”选项来实现的。
  • 执行程序,观察并记录发生分支延迟的时刻,记录该程序执行的总时钟周期数。
  • 假设延迟槽为一个,自己对 branch.s 程序进行指令调度(自己修改源程序),将调度后的程序重新命名为 my-branch.s。

6.使用 MIPS 指令实现求两个数组的点积

  • 样例程序array.s,该程序的功能为实现求两个n维向量A,B的点积。
  • 载入程序(array.s),观察流水线输出结果。
  • 使用定向功能再次执行代码,与刚才执行结果进行比较,观察执行效率的不同。
  • 采用静态调度方法重排指令序列,减少相关,优化程序,分析执行结果和效率。
  • 利用分支延迟,分析流水线的性能

实验分析和总结

三个代码:

Schedule.s

代码:

.text
main:
ADDIU  $r1,$r0,A
LW     $r2,0($r1)
ADD    $r4,$r0,$r2
SW     $r4,0($r1)
LW     $r6,4($r1)
ADD    $r8,$r6,$r1
MUL    $r12,$r10,$r1
ADD    $r16,$r12,$r1
ADD    $r18,$r16,$r1
SW     $r18,16($r1)
LW     $r20,8($r1)
MUL    $r22,$r20,$r14
MUL    $r24,$r26,$r14
TEQ    $r0,$r0
.data
A: 
.word 4,6,8

由于数据相关产生的延迟,总共需要32个周期才可以完成整个程序。
对程序进行修改:

.text
main:
ADDIU  $r1,$r0,A
MUL    $r24,$r26,$r14
LW     $r2,0($r1)
SW     $r4,0($r1)
LW     $r6,4($r1)
LW     $r20,8($r1)
ADD    $r4,$r0,$r2
ADD    $r8,$r6,$r1
MUL    $r12,$r10,$r1
ADD    $r16,$r12,$r1
MUL    $r22,$r20,$r14
ADD    $r18,$r16,$r1
SW     $r18,16($r1)
TEQ     $r0,$r0
.data
A:
.word 4,6,8

改进过后,执行完程序需要23个周期。

Branch.s

源代码:

.text
main:
ADDI  $r2,$r0,1024    ;立即数相加
ADD   $r3,$r0,$r0     ;整数相加
ADDI  $r4,$r0,8       ;立即数相加
loop:  ;循环指令
LW    $r1,0($r2)      ;r2+0取出送到r1
ADDI  $r1,$r1,1       ;立即数相加
SW    $r1,0($r2)      ;r1取出送到r2+0
ADDI  $r3,$r3,4       ;立即数相加
SUB   $r5,$r4,$r3     ;整数相减
BGTZ  $r5,loop        ;大于5,则转移成功,否则继续进行取数循环
ADD   $r7,$r0,$r6     ;整数相加
TEQ   $r0,$r0

第一次分支延迟是由于控制相关,第二次分支延迟是由于数据相关。程序的总周期数为37个。
改进后:
在loop循环中,SW指令没有必要多次循环执行,所以可以将SW从loop循环中取出,然后对loop循环中的其他指令进行调度执行。

.text
main:
ADDI  $r2,$r0,1024    #立即数相加,结果存入r2
ADD   $r3,$r0,$r0     #整数相加,结果存入r3
ADDI  $r4,$r0,8       #立即数相加,结果存入r4
LW    $r1,0($r2)      #从loop循环中取出,作为第一次调用,之后可不再重复调用

loop:  
ADDI  $r3,$r3,4       #立即数相加,结果存入r3
ADDI  $r1,$r1,1       #整数相加,结果存入r1
SUB   $r5,$r4,$r3     #整数相减,结果存入r5
SW    $r1,0($r2)      #取出r1,放在r2+0中
BGTZ  $r5,loop        #大于5,成功转移;否则继续进行循环。与r5相距较远,防止出现数据相关

LW    $r1,0($r2)      #开启延迟槽时可做为延迟槽
ADD   $r7,$r0,$r6     #整数相加,不必多次循环
TEQ   $r0,$r0         #自陷,程序结束

改进后需要26个周期。

Array.s

没有加定向的执行结果:
共需要157个执行周期。
加定向后的实验结果:
执行周期总数为117个。
加定向后,程序效率提高,所需要的执行周期数变少。
修改优化:

.text main: 
ADDIU $r1,$r0,array1     #取A的地址
ADDIU $r2,$r0,array2     #取B的地址
ADDIU $r3,$r0,10         #数组容量为10,设置相乘的次数,向量内的数量为10
ADDIU $r10,$r0,0         #r10保存最终结果,初始化为0
LW $r4,0($r1)            #对应位取数,从loop循环中取出,可减少重复执行,从目标除调度,
loop: 
LW $r5,0($r2)            #取r2+0,存入到r5。
ADDI $r1,$r1,4           #地址加,变为下一个数(word)地址
ADDI $r3,$r3,-1          #计数器r3减一
MUL $r6,$r4,$r5          #取出的数相乘存放到r6
ADDI $r2,$r2,4           #地址加,变为下一个数(word)地址
ADD $r10,$r10,$r6        #存入r10
BGTZ $r3,loop            #计数器r3仍大于零则跳转,说明数组没到末尾,与r3相距较远,不会出现数据冲突

LW $r4,0($r1)            #作为延迟槽,放在BGTZ之后
TEQ $r0,$r0              #自陷,程序结束
.data 
array1: .word 0,1,2,0,1,2,3,0,1,2 
array2: .word 0,1,2,0,1,2,3,0,1,2

不加定向:
执行周期个数为100个。
加定向:
执行周期数为90个。

实验分析和总结:

1、数据相关可以使用指令调度的方法来解决,可以有效提高效率,改进速度,减少指令执行周期的个数。
2、循环指令的优化可以使用指令调度、循环展开或者两者相结合的方式来进行改进。
3、指令优化可以先对原指令进行分析,看所紧邻的两条指令所需要的寄存器是否有冲突,可以通过有限次的指令顺序改变,来调整,防止出现数据相关。
4、分支延迟槽就是分支指令后的一条指令,可以利用这条指令提高分支指令的循环效率,但不是很明显,作为延迟槽的指令可以是循环指令中的一条指令。

你可能感兴趣的:(计算机体系结构)