北邮高级计算机系统结构实验二三四五.docx
《北邮高级计算机系统结构实验二三四五.docx》由会员分享,可在线阅读,更多相关《北邮高级计算机系统结构实验二三四五.docx(38页珍藏版)》请在冰豆网上搜索。
![北邮高级计算机系统结构实验二三四五.docx](https://file1.bdocx.com/fileroot1/2022-11/28/f8122bb3-15e9-4de4-bbd0-6500addcfd2e/f8122bb3-15e9-4de4-bbd0-6500addcfd2e1.gif)
北邮高级计算机系统结构实验二三四五
实验二指令流水线相关性分析
·实验目的
通过使用WINDLX模拟器,对程序中的三种相关现象进行观察,并对使用专用通路,增加运算部件等技术对性能的影响进行考察,加深对流水线和RISC处理器的特点的理解。
·实验原理:
指令流水线中主要有结构相关、数据相关、控制相关。
相关影响流水线性能。
@
·实验步骤
一.使用WinDLX模拟器,对做如下分析:
(1)观察程序中出现的数据/控制/结构相关。
指出程序中出现上述现象的指令组合。
(2)考察增加浮点运算部件对性能的影响。
(3)考察增加forward部件对性能的影响。
(4)观察转移指令在转移成功和转移不成功时候的流水线开销。
·实验过程
一.;
二.使用WinDLX模拟器,对做如下分析:
浮点加、乘、除部件都设置为1,浮点数运算部件的延时都设置为4,如图1:
图1初始设置
将和加载至WinDLX中,如图2示。
!
图2加载程序
1.观察程序中出现的数据/控制/结构相关;指出程序中出现上述现象的指令组合。
1)数据相关
点击F7,使程序单步执行,当出现R-Stall时停止,运行过程中出现下图3所示,输入整数6。
'
图3输入整数6
打开ClockDiagram,可以清楚的看到指令执行的流水线如图4所示。
图4指令流水线
双击第一次出现R-Stall的指令行,如图5所示。
图5指令详细信息
对以上出现的情况分析如下:
、
程序发生了数据相关,R-Stall(R-暂停)表示引起暂停的原因是RAW。
lbur3,0×0(r2)
要在WB周期写回r3中的数据;而下一条指令
seqir5,r3,0×a
要在intEX周期中读取r3中的数据。
上述过程发生了WR冲突,即写读相关。
为了避免此类冲突,
seqr5,r4,0×a的intEX指令延迟了一个周期进行。
由此,相关指令为:
2)控制相关
。
由图6可以看出,在第4时钟周期:
第一条指令处于MEM段,第二条命令处于intEX段,第三条指令出于aborted状态,第四条命令处于IF段。
图6指令流水线
《
以上情况原因分析:
在窗口中,模拟处于第四时钟周期,第3条命令指示为:
“aborted”。
原因是:
第二条命令jalInputUnsigned是无条件分支指令,在第4个时钟周期,jal指令执行intEX周期之后才知道转移的位置,下一条指令应该执行swSaveR2(r0),r2指令。
但之前jalInputUnsigned的下一条命令movi2fp已经取出,所以需要将该指令流水清空,即movi2fp的执行应被取消,在流水线中留下气泡。
3)结构相关
首先,我们先来看一下执行过控制相关的时空图和Pipeline,如下图7所示。
…
图7控制相关
图8控制相关的Pipeline
当我们点击Pipeline中IF所对应的框框可以看到详细的该指令执行情况,如下图9所示。
…
图9指令详情
图9表明了addir2,r2,0×1的详细信息。
该指令与它前一条指令addr1,r1,r3发生了结构相关。
并且由于此处的冲突,需要暂停2个周期。
在ID段暂停后,则开始进图intEX段。
所以这条指令(addir2,r2,0×1)你不能进入ID流水段,译码部分占用,发生了结构相关。
该部分的指令为:
1..
2.考察增加浮点运算部件对性能的影响。
该实验取N=6
首先通过Configuration,点击FloatingPointStageConfiguration来设置浮点运算部件的配置。
实验要求所有浮点运算部件的延时都请设定为4个周期,所以我们将Delay这一栏改成4,而Count可以任意,为了对比,我们第一次浮点运算部件取全部为1,第二次浮点运算部件取全部为2。
如下图所示:
运行50个cycles之后,可以看到他们数据的对比:
^
由此可见,浮点运算部件的增减对效率无影响。
比较各个数据,发现没有变化。
无论怎么增加浮点运算部件,统计结果都一样。
原因在于此程序中浮点计算指令没有重叠,所以并行度没有增加,性能没有提高。
3.考察增加forward部件对性能的影响。
为了对比有无forward部件的性能。
需要在Configuration中勾选enableforwarding,以及不勾选enableconfiguration来看性能数据的对比,不使用forward部件和使用forward部件:
"
从上面的数据我们可以看出增加forward部件后RAW由原来占总时钟周期的26%减少至18%,RAW个数由原来的13减少至9。
增加forward部件使得控制相关比例增加了。
即,使用forward部件后,总的时钟周期减少,数据相关减少,流水线的性能得到一定的改善。
4.观察转移指令在转移成功和转移不成功时候的流水线开销。
我们假设,浮点部件设置Count=1,Delay=4;N=6。
执行50个cycles完毕后,查看条件转移分支,如下图所示:
由上图可知,转移指令一共2条,成功转移1条(占50%),不成功为1条。
所以,静态指令调度算法只能解决数据相关,条件转移结果与原来相比没有变化。
即,若转移不成功,对流水线的执行无影响,流水线的吞吐率和效率没有降低;若转移成功,则要废弃预先读入的指令,重新从转移成功处读入指令,执行效率会下降。
#
·实验总结
通过本次试验,不仅更加熟悉了WinDLX模拟器的使用以及对其基础功能的认识,而且通过单步执行程序,观察三种相关的出现,以及思考出现的原因,是我更加深入了解了流水线。
#
【
)
^
:
:
实验三DLX处理器程序设计
·实验目的:
学习使用DLX汇编语言编程,进一步分析相关现象
·实验原理:
掌握向量运算算法和编程方法。
·实验内容和要求:
~
自编一段汇编代码,完成两双精度浮点一维向量的加法(或乘除法)运算,并输出结果。
向量长度>=16。
观察程序中出现的数据/控制/结构相关
·实验步骤:
一.熟悉DLX汇编语言。
(1)汇编器处理汇编文件时,数据位于内存中data指针所指向的空间,指令位于text指针所指向的空间。
(2)Trap0是通知WINDLX模拟器程序结束,Trap5是输出格式化到标准输出
]
二.编写两双精度浮点一维向量的加法运算程序。
代码清单如下:
.data
V1:
.double,,,,,,,,,,,,,,,
V2:
.double,,,,,,,,,,,,,,,
!
a:
.asciiz"result="
c:
.asciiz"%f"
.align2
d:
.wordc
dizhi:
.space8
(
.text
.globalmain
main:
addir1,r0,a
swdizhi,r1;存储字,保存a的首地址
.
addir14,r0,dizhi
trap5;输出字符串"result="
addir10,r0,0;r10=0
addir8,r0,20;r8=20,即向量的长度
loop:
】
ldf2,V1(r10)
ldf4,V2(r10)
adddf2,f2,f4;将V1,V2的相应项依次相加,保存在f2
sddizhi,f2;存储双精度浮点数f2
addir14,r0,d
】
trap5;输出结果
addir10,r10,8;取V1,V2下一项
subir8,r8,1;循环次数减一
bnezr8,loop;假如r8!
=0,则返回到loop
trap0;结束
~
运行完毕之后出现:
运行结果如下:
1.观察程序中出现的数据/控制/结构相关
(
本次实验执行过程共出现RAW数据相关80次,控制相关15次,trap54次,共有stall149次。
具体如下:
1)数据相关
~
2)T-stall
3)控制相关
^
2.考察增加浮点运算部件对性能的影响。
比较浮点运算部件分别为1和2时,
接下来查看Statistis进行比较,如下图
:
由以上两图可得,本实验增加浮点运算部件对流水线性能没有影响。
3.增加FORWARD部件对性能的影响。
为了对比有无forward部件的性能。
需要在Configuration中勾选enableforwarding,以及不勾选enableconfiguration来看性能数据的对比,不使用forward部件和使用forward部件:
从上面的数据我们可以看出增加forwardi部件后,时钟周期由368减少至301个,RAW由原来占总时钟周期的%减少至%;RAW个数由原来的147减少至80;增加forward部件使得控制相关比例增加了,但是数目并没有增加。
总而言之,使用forward部件后,总的时钟周期减少,数据相关减少,流水线的性能得到一定的改善。
、
4.观察转移指令在转移成功和转移不成功时候的流水线开销。
由上图可得,转移指令一共16条,其中成功转移15条,占%,不成功转移1条,占5%。
静态指令调度算法是在出现数据相关时,为了消除或者减少流水线空转,编译器确定并分离出程序中存在在相关的指令,然后进行指令调度,并对代码优化。
但是静态指令调度只能解决数据相关,条件转移结果与原理来相比没有变化。
若转移不成功,对流水线的执行无影响,流水线的吞吐率和效率没有降低。
若转移成功,则要废弃预先读入的指令,重新从转移成功处读入指令,每执行一条条件转移指令,一条x段流水线就有x-2个流水线被浪费掉,执行效率降低,性能有一定的损失。
·实验总结
/
加深了对汇编语言的理解与运用,尤其是trap5,输出格式化到标准输出的理解,在代码中,应注意:
相加的结果要保存到dizhi这个变量中,否则即使运算正确也不能把结果输出。
:
、
《
)
|
)
~
-
实验四代码优化
·实验目的:
学习简单编译优化方法,观察采用编译优化方法所带来的性能的提高。
…
·实验原理:
采用静态调度方法重排指令序列,减少相关,优化程序。
·实验步骤:
1.优化实验3程序代码清单及注释说明
.data
^
V1:
.double,,,,,,,,,,,,,,,
V2:
.double,,,,,,,,,,,,,,,
a:
.asciiz"result="
c:
.asciiz"%f"
.align2
/
d:
.wordc
dizhi:
.space8
.text
.globalmain
main:
/
addir1,r0,a;该指令与swdizhi,r1存在RAW相关,故将addir8,r0,16和addir8,r0,16加到中间
addir10,r0,0;该指令与ldf2,V1(r10)存在RAW相关,故将其提前
addir8,r0,16
swdizhi,r1
addir14,r0,dizhi
(
trap5
loop:
ldf2,V1(r10)
ldf4,V2(r10)
addir10,r10,8
~
subir8,r8,1
adddf2,f2,f4;该指令与前面两条指令均存在RAW相关,将其延后执行
addir14,r0,d
sddizhi,f2;该指令与adddf2,f2,f4存在RAW相关,将其延后执行
trap5
$
bnezr8,loop
trap0
执行完毕后,我们点击Statistics查看运行结果数据分析
2.程序相关性分析结果
…
左图是优化前的,右图是优化后的
由上述两图对比可以看出,数据相关:
其RAW相关由优化前的%减少为%,性能改善很多;控制相关:
由原来的%变为%,数量没变,没有改善。
因此,可以看出,我所进行的代码优化对性能方面改善并不是很强烈,主要影响还是在数据相关方面.
3.增加浮点运算部件对性能的影响。
比较浮点运算部件Count分别为1和2时,
…
接下来查看Statistis进行比较,如下图
由以上两图可得,本实验增加浮点运算部件对流水线性能没有影响。
4.增加FORWARD部件对性能的影响。
'
从上面的数据我们可以看出增加forwardi部件后:
时钟周期由285减少至253个,RAW由原来占总时钟周期的%减少至%;RAW个数由原来的64减少至32;增加forward部件使得控制相关比例增加了,但是数目并没有增加。
总而言之,使用forward部件后,总的时钟周期减少,数据相关减少,流水线的性能得到一定的改善。
5.观察转移指令在转移成功和转移不成功时候的流水线开销。
由上图可得,转移指令一共16条,其中成功转移15条,占%,不成功转移1条,占%。
优化对于转移指令并无影响。
静态指令调度算法是在出现数据相关时,为了消除或者减少流水线空转,编译器确定并分离出程序中存在在相关的指令,然后进行指令调度,并对代码优化。
但是静态指令调度只能解决数据相关,条件转移结果与原理来相比没有变化。
若转移不成功,对流水线的执行无影响,流水线的吞吐率和效率没有降低。
若转移成功,则要废弃预先读入的指令,重新从转移成功处读入指令,每执行一条条件转移指令,一条x段流水线就有x-2个流水线被浪费掉,执行效率降低,性能有一定的损失。
·解决的困难、解决方法和实习体会
代码优化的关键在于相关性的分析,它关系到能否进行优化以及怎么优化。
采用静态调度方法重排指令序列要保证调整顺序之后不影响指令执行。
若两条相邻的指令存在RAW相关时,在重排指令的时候,该两条指令之间插入至少两条其它指令才能保证消除stall。
相邻的指令访问相同的寄存器并不代表就会存在冲突,比如指令:
&
addir1,r0,a
addir10,r0,0
addir8,r0,16
以上三条指令均需要访问寄存器r0,但是由于都是读r0,所以不存在冲突。
代码优化的目的就是减少相关性的发生,提高流水线的效率。
经过代码优化这一实验后,我更加深入理解了相关性的概念。
此外,采用静态调度方法重排指令序列与forwarding技术相结合,可以提高流水线的效率。
;
¥
"
》
:
\
:
实验五循环展开(选作)
实验目的:
进一步学习DLX汇编语言编程方法,学习循环展开编译优化方法,观察采用循环展开编译优化方法所带来的性能的提高。
实验原理:
对循环程序采用循环展开(loopunrolling)方法进行优化,减少相关。
}
实验步骤:
1.编写矩阵相乘程序
(1)主要实现的C代码如下
doubles1=;
for(inti=0;i<10;i++)
:
for(intj=0;j<10;j++)
{
MA[i][j]=s1;
MB[i][j]=s1;
}
、
for(inti=0;i<10;i++)
for(intj=0;j<10;j++)
{
for(doubledata=0,intk=0;k<10;k++)
data+=MA[i][k]*MB[k][j];
·
MC[i][j]=data;
}
(2)用windlx编写的汇编指令如下:
.data
MA:
.space400
…
MB:
.space400
MC:
.space400
s1:
.float
.text
.globalmain
、
main:
addir1,r0,MA;将MA的地址赋给r1
addir3,r0,MB;将MB的地址赋给r3
addir11,r1,#400;MA的末地址
lff2,s1
】
;对矩阵MAMB进行初始化
init:
sf0(r1),f2;将f2的值赋给MA[i][j]
sf0(r3),f2
addir1,r1,#4
"
addir3,r3,#4
sltr2,r1,r11;比较r1和MA的末地址是否相等
bnezr2,init;不等则继续循环
;主循环开始
addir21,r0,#40;常量
^
addir22,r0,#10;常量
addir23,r0,#4
addir29,r0,#0
addir7,r29,#0;i=0
loop1:
.
addir8,r29,#0;j=0
loop2:
addir9,r29,#0;k=0;
movi2fpf0,r29;data=0给变量赋0
;下面开始第三层的主循环
>
loop3:
multur11,r7,r21;r11=i*40
multur1,r9,r23;r1=k*4
addur11,r11,r1;计算出MA[i][k]的地址
ldf2,MA(r11)
;
multur13,r9,r21;r13=k*40
multur1,r8,r23;r1=j*4
addur13,r13,r1;计算出MB[k][j]的地址
ldf4,MB(r13)
[
multff6,f2,f4
addff0,f0,f6;data+=MA[i][k]*MB[k][j];
addir9,r9,#1;k++;
sltr2,r9,r22;r9即k是否等于10
bnezr2,loop3;不等继续循环
、
;那么这里要完成这个操作MC[i][j]=data;
multur13,r7,r21;r13=i*40
multur1,r8,r23;r1=j*4
addur13,r13,r1;计算MC[i][j]的地址
sfMC(r13),f0
}
addir8,r8,#1
sltr2,r8,r22;r8即j是否等于10
bnezr2,loop2;不等继续循环
addir7,r7,#1
—
sltr2,r7,r22;r7即i是否等于10
bnezr2,loop1;不等继续循环
trap0;endofprogram
运行结果如下:
"
由于没有写输出语句,所以可以从Register中看到我们想要的结果(相乘的结果存在F0中)
2.观察程序中出现的数据/控制/结构相关
本次实验执行过程共出现RAW数据相关2284次,控制相关78次,trap66次,共有stall2860次。
具体如下:
1)数据相关和结构相关
;
multff6,f2,f4与addf0,f0,f6数据相关前一指令要写入f6而后一条要读f6造成WR相关add指令要等四个周期同时addr9,r9,0x1与前一条指令的冲突,这一条指令等待ID单元空出。
2)控制相关
)
bnezr2,loop3发生跳转在intEX才执行立马阻止multur13,r7,r21指令的译码,要清空后面点流水线,这条乘法指令出现aborted异常。
3.考察增加浮点运算部件对性能的影响。
比较浮点运算部件分别为1和2时。
>
接下来查看Statistis进行比较,如下图
可以看出增加运算单元会增加CPI从691条指令增加到710条,主要是结构相关从%减少到0,例如:
¥
可以使相邻的乘法指令并行执行。
4.增加FORWARD部件对性能的影响。
、
从上面的数据我们可以看出增加forwardi部件后RAW由原来占总时钟周期的30%减少至%,RAW个数由原来的300减少至167。
增加forward部件使得控制相关比例增加了,使得部件使用更紧凑了,S-Tall从0增加到了36。
但总体相关还是减少的,即,使用forward部件后,总的时钟周期减少,数据相关减少,流水线的性能得到一定的改善。
5.观察转移指令在转移成功和转移不成功时候的流水线开销。
我们假设,浮点部件设置Count=1,Delay=4。
执行完毕后,查看条件转移分支,如下图所示:
由上图可知,转移指令一共106条,成功转移105条(占%),不成功为1条。
所以,静态指令调度算法只能解决数据相关,条件转移结果与原来相比没有变化。
即,若转移不成功,对流水线的执行无影响,流水线的吞吐率和效率没有降低;若转移成功,则要废弃预先读入的指令,重新从转移成功处读入指令,执行效率会下降。
5.使用循环展开手工优化程序
.data
MA:
.space400
MB:
.space400
MC:
.space400
s1:
.float
.text
.globalmain
main:
addir1,r0,MA;将MA的地址赋给r1
addir3,r0,MB;将MB的地址赋给r3
addir11,r1,#400;MA的末地址
lff2,s1
;对矩阵MAMB进行初始化
init:
sf0(r1),f2;将f2的值赋给MA[i]
sf0(r3),f2
addir1,r1,#4
addir3,r3,#4
sltr2,r1,r11;比较r1和MA的末地址是否相等
bnezr2,init;不等则继续循环
;主循环开始
addir21,r0,#40;常量
addir22,r0,#10;常量
addir23,r0,#4
addir29,r0,#0
addir7,r29,0;i=0
loop1:
addir8,r29,0;j=0
multur11,r7,r21;r11=i*40
loop2:
addir9,r29,0;k=0;
movi2fpf0,r29;data=0给变量赋0
multur1,r8,r23;r1=j*4
;下面开始第三层的主循环
loop3:
multur1,r9,r23;r1=k*4
addur11,r11,r1;计算出MA[i][k]的