余伦静影响流水线的性能和解决方法.docx
《余伦静影响流水线的性能和解决方法.docx》由会员分享,可在线阅读,更多相关《余伦静影响流水线的性能和解决方法.docx(14页珍藏版)》请在冰豆网上搜索。
![余伦静影响流水线的性能和解决方法.docx](https://file1.bdocx.com/fileroot1/2023-4/28/23fea94b-9b90-4f91-9fbc-c8eea380a4fc/23fea94b-9b90-4f91-9fbc-c8eea380a4fc1.gif)
余伦静影响流水线的性能和解决方法
影响流水线性能的因素与解决办法
借鉴了工业流水线制造的思想,现代CPU也采用了流水线设计。
在工业制造中采用流水线可以提高单位时间的生产量;同样在CPU中采用流水线设计也有助于提高CPU的频率。
先让我们以汽车装配为例来解释流水线的工作方式。
假设装配一辆汽车需要4个步骤:
1.冲压:
制作车身外壳和底盘等部件,2.焊接:
将冲压成形后的各部件焊接成车身,3.涂装:
将车身等主要部件清洗、化学处理、打磨、喷漆和烘干,4.总装:
将各部件(包括发动机和向外采购的零部件)组装成车;同时对应地需要冲压、焊接、涂装和总装四个工人。
如果不采用流水线,那么第一辆汽车依次经过上述四个步骤装配完成之后,下一辆汽车才开始进行装配,最早期的工业制造就是采用的这种原始的方式。
不久之后大家就发现,某个时段中一辆汽车在进行装配时,其它三个工人处于闲置状态,显然这是对资源的极大浪费!
于是大家开始思考能有效利用资源的方法:
有什么办法让四个工人一起工作呢?
那就是流水线!
在第一辆汽车经过冲压进入焊接工序的时候,立刻开始进行第二辆汽车的冲压,而不是等到第一辆汽车经过全部四个工序后才开始。
之后的每一辆汽车都是在前一辆冲压完毕后立刻进入冲压工序,这样在后续生产中就能够保证四个工人一直处于运行状态,不会造成人员的闲置。
这样的生产方式就好似流水川流不息,因此被称为流水线。
CPU的工作我们也可以大致分为指令的获取、解码、运算和结果的写入四个步骤,采用流水线设计之后,指令(好比待装配的汽车)就可以连续不断地进行处理。
在同一个较长的时间段内,显然拥有流水线设计的CPU能够处理更多的指令。
Intel和AMD在桌面CPU市场上的激烈竞争,使双方都千方百计地拿出更强大产品来压制对方,而最引人瞩目的就是CPU的频率之争。
随着CPU频率不断地攀升,Intel总是在自己某个核心的处理器到达极限之时采用新的、更长流水线的核心来消除频率的瓶颈。
那么流水线和频率之间有什么关系呢?
还是以上面的例子来说明。
假如冲压、焊接、涂装和总装四个过程各自需要1个小时,现在我们把这四个工序细化:
冲压分为冲压1(外壳)和冲压2(底盘)两个子工序,另外三个工序同样各自分成两个子工序,一共八个子工序。
这样一来,完成每个子工序平均只需要半个小时,因此每隔半个小时就有一辆汽车完成装配,下线速度提高了一倍!
如果再进一步细化,一分为二,那么完成每个工序平均只需要15分钟,即每隔15分钟就有一辆汽车下线,速度又提高了一倍(单辆汽车的生产时间仍是4个小时,但是两辆汽车的生产间隙更小了)。
所以工序分得越细,单位时间内(例如8个小时)生产的汽车就越多。
正是这样,CPU厂商才试图不断加长流水线,以利于频率的提升。
那么为什么Prescott核心的处理器才31级流水线,流水线级数能不能无限增长呢
首先,由于现有芯片制造工艺的限制,频率的提升带来高功耗、高发热量的问题。
尽管流水线增长,频率提升的空间相应增大,但是处理器频率提升的其它瓶颈却无法解决。
而且过长的流水线意味着更加复杂的内部结构,生产的良品率也难以保证。
其次,在CPU的工作中,指令往往不是孤立的,许多指令按一定的顺序执行才能完成一个任务。
而一旦某个指令在运算过程中发生了错误,或者执行了没有用的指令,那么其后与之相关的指令就都没有用了。
这些指令必须清除掉,然后再执行其它的指令,CPU相当于做了许多无用功!
流水线越长,一旦出错影响也就越大,比如一个指令在最后一级出错,那么可能在后续流水线中的所有指令都要被清除,Northwood核心处理器要浪费20级工序的时间,而Prescott核心处理器就要浪费31级工序的时间!
最基本的CPU流水线分成5级,如果将每一步细化便可以扩展到10级。
流水线必须实现相同的目标:
引入指令,输出结果,但级数的不同会让效率发生变化。
5级流水线每一步花费的工作量要比十级流水线更大。
如果其他保持不变,那么我会选择5级流水线,因为实现5级数据处理更加容易,如果每一级不能保持全速运算,那CPU的效率会大大下降。
选择更多流水线的理由是,如果每一级的处理过程更简单,那处理的速度会加快。
最复杂的那一级会是整个运算中最慢的一环,它将决定整体的运行速度。
如果我们假设5级流水线的每一级都要花费1ns来完成,每一级运算的周期为一个时钟频率,那么我们得到了1GHz的处理速度。
当我们增加线管级数时,这时很难保证每一级都全速运行,我们必须通过缩短每一级运算的周期来进行弥补。
庆幸的是,由于每个时钟频率的工作量减少了,我们能有效缩短周期,在后者的设计中,时钟周期可以缩短到0.5ns。
十级流水线实现了2GHz的运行频率,它是前者运行频率的两倍。
如果我们假定每一级流水线都全速工作,那么它的性能也将是前者的两倍。
但现实是,流水线不可能每刻都处于满负荷状态,因此市场上的2GHzCPU不可能有1GHzCPU两倍的性能。
对于CPU来说,它的工作可分为获取指令、解码、运算、结果几个步骤。
其中前两步由指令控制器完成,后两步则由运算器完成。
按照传统的方式,所有指令按顺序执行,先由指令控制器工作,完成一条指令的前两步,然后运算器工作,完成后两步,依此类推……很明显,当指令控制器工作时运算器基本上处于闲置状态,当运算器在工作时指令控制器又在休息,这样就造成了相当大的资源浪费。
于是CPU借鉴了工业生产中被广泛应用的流水线设计,当指令控制器完成了第一条指令的前两步后,直接开始第二条指令的操作,运算器单元也是,这样就形成了流水线。
流水线设计可最大限度地利用了CPU资源,使每个部件在每个时钟周期都在工作,从而提高了CPU的运算频率。
影响流水线性能的因素:
流水线处理方式是一种时间重叠并行处理的处理技术,具体地说,就是流水线可以在同一个时间启动2个或以上的操作,借此来提高性能。
为了实现这一点,流水线必须要时时保持畅通,让任务充分流水,但在实际中,会出现2种情况使流水线停顿下来或不能启动:
1、多个任务在同一时间周期内争用同一个流水段。
例如,假如在指令流水线中,如果数据和指令是放在同一个储存器中,并且访问接口也只有一个,那么,两条指令就会争用储存器;在一些算数流水线中,有些运算会同时访问一个运算部件……
2、数据依赖。
比如,A运算必须得到B运算的结果,但是,B运算还没有开始,A运算动作就必须等待,直到A运算完成,两次运算不能同时执行。
不过,就算是这样,我们也不用担心,因为对于第一种情况,我们可以增加运算部件的数量来使他们不必争用同一个部件;第二种情况,我们可以用指令调度的方法重新安排指令或运算的顺序。
流水线是现代RISC核心的一个重要设计,它极大地提高了性能。
对于一条具体的指令执行过程,通常可以分为五个部分:
取指令,指令译码,取操作数,运算(ALU),写结果。
其中前三步一般由指令控制器完成,后两步则由运算器完成。
按照传统的方式,所有指令顺序执行,那么先是指令控制器工作,完成第一条指令的前三步,然后运算器工作,完成后两步,在指令控制器工作,完成第二条指令的前三步,在是运算器,完成第二条指令的后两部……很明显,当指令控制器工作是运算器基本上在休息,而当运算器在工作时指令控制器却在休息,造成了相当大的资源浪费。
解决方法很容易想到,当指令控制器完成了第一条指令的前三步后,直接开始第二条指令的操作,运算单元也是。
这样就形成了流水线系统,这是一条2级流水线。
如果是一个超标量系统,假设有三个指令控制单元和两个运算单元,那么就可以在完成了第一条指令的取址工作后直接开始第二条指令的取址,这时第一条指令在进行译码,然后第三条指令取址,第二条指令译码,第一条指令取操作数……这样就是一个5级流水线。
很显然,5级流水线的平均理论速度是不用流水线的4倍。
流水线系统最大限度地利用了CPU资源,使每个部件在每个时钟周期都工作,大大提高了效率。
但是,流水线有两个非常大的问题:
相关和转移。
在一个流水线系统中,如果第二条指令需要用到第一条指令的结果,这种情况叫做相关。
以上面哪个5级流水线为例,当第二条指令需要取操作数时,第一条指令的运算还没有完成,如果这时第二条指令就去取操作数,就会得到错误的结果。
所以,这时整条流水线不得不停顿下来,等待第一条指令的完成。
这是很讨厌的问题,特别是对于比较长的流水线,比如20级,这种停顿通常要损失十几个时钟周期。
目前解决这个问题的方法是乱序执行。
乱序执行的原理是在两条相关指令中插入不相关的指令,使整条流水线顺畅。
比如上面的例子中,开始执行第一条指令后直接开始执行第三条指令(假设第三条指令不相关),然后才开始执行第二条指令,这样当第二条指令需要取操作数时第一条指令刚好完成,而且第三条指令也快要完成了,整条流水线不会停顿。
另一个大问题是条件转移。
在上面的例子中,如果第一条指令是一个条件转移指令,那么系统就会不清楚下面应该执行那一条指令?
这时就必须等第一条指令的判断结果出来才能执行第二条指令。
条件转移所造成的流水线停顿甚至比相关还要严重的多。
所以,现在采用分支预测技术来处理转移问题。
虽然我们的程序中充满着分支,而且哪一条分支都是有可能的,但大多数情况下总是选择某一分支。
比如一个循环的末尾是一个分支,除了最后一次我们需要跳出循环外,其他的时候我们总是选择继续循环这条分支。
根据这些原理,分支预测技术可以在没有得到结果之前预测下一条指令是什么,并执行它。
现在的分支预测技术能够达到90%以上的正确率,但是,一旦预测错误,CPU仍然不得不清理整条流水线并回到分支点。
这将损失大量的时钟周期。
所以,进一步提高分支预测的准确率也是正在研究的一个课题。
越是长的流水线,相关和转移两大问题也越严重,所以,流水线并不是越长越好,超标量也不是越多越好,找到一个速度与效率的平衡点才是最重要的。
下面是有关于我们在实验中做过解决数据相关的方法如下所示:
实验内容:
1、在不采用定向技术的情况下,用WinDLX模拟器运行程序data_d.s.。
2、记录数据相关引起的暂停时钟周期数以及程序执行的总时钟周期数,计算暂停时钟周期数占总执行周期数的百分比。
暂停时钟周期数占总执行周期数的百分比为:
5%
3、在采用定向技术的情况下,用WinDLX模拟器再次运行程序data_d.s。
4、记录数据相关引起的暂停时钟周期数以及程序执行的总时钟周期数,计算暂停时钟周期数占总执行周期数的百分比。
暂停时钟周期数占总执行周期数的百分比为:
8%
5、根据上面记录的数据,计算采用定向技术后性能提高的倍数。
采用定向技术后性能提高的倍数为:
1.6倍
6、用WinDLX模拟器运行调度前的程序sch-befores.s,记录程序执行过程中各种相关发生的次数以及程序执行的总时钟周期数。
7、用WinDLX模拟器运行调度后的程序sch-after.s,记录程序执行过程中各种相关发生的次数以及程序执行的总时钟周期数。
8、根据记录结果,比较调度前和调度后的性能,分析其原因。
调度后程序执行的总时钟周期数比调度前快6个周期,
调度前程序:
.data
.globalONE
ONE:
.word1
.text
.globalmain
main:
lff1,ONE;turndivfintoamove
cvti2ff7,f1;bystoringinf71in
nop;floating-pointformat
divff1,f8,f7;moveY=(f8)intof1
divff2,f9,f7;moveZ=(f9)intof2
addff3,f1,f2;f3+f1=f2
divff10,f3,f7;movef3intoX=(f10)
divff4,f11,f7;moveB=(f11)intof4
divff5,f12,f7;moveC=(f12)intof5
multff6,f4,f5;f6*f4=f5
divff13,f6,f7;movef6intoA=(f13)
Finish:
trap0
调度后程序
.data
.globalONE
ONE:
.word1
.text
.globalmain
main:
lff1,ONE;turndivfintoamove
cvti2ff7,f1;bystoringinf71in
nop;floating-pointformat
divff1,f8,f7;moveY=(f8)intof1
divff2,f9,f7;moveZ=(f9)intof2
divff4,f11,f7;moveB=(f11)intof4
divff5,f12,f7;moveC=(f12)intof5
addff3,f1,f2;f3+f1=f2
multff6,f4,f5;f6*f4=f5
divff10,f3,f7;movef3intoX=(f10)
divff13,f6,f7;movef6intoA=(f13)
Finish:
trap0
调度前由于F1,F2及F4,F5数据相关,下一条指令必须等前一条指令执行完后才能开始执行,指令之间的执行都要浪费时间周期。
调度后消除了加法及乘法指令之间的数据相关,重新调整了指令序列,所以执行速度快了。
9、通过Configuration菜单中的“Floatingpointstages”选项,把除法单元数设置为3,把加法﹑乘法﹑除法的延迟设置为3个时钟周期,重做上述三步。
调度前:
调度后:
由于Floatingpoint的除法单元数设置为3,增加了流水线的某些执行功能,这样就加快了指令的执行。
实验总结
通过这次综合实验,加深了对第五章节的理解,关于流水线的部分总结如下为提高计算机的执行性能,可将处理器的程序控制逻辑和执行部件构造成流水线的形式。
一条m段的指令流水线最高可以重叠m条指令的执行,性能可以达到每个时钟周期完成一条指令的执行。
一般指令流水线包含5个或更多的阶段。
为保证流水线的有效工作,要求流水线在工作过程中要预防、避免冲突和相关。
冲突是指不同指令使用相同的流水线阶段引起的,主要发生在与存储器操作阶段有关的阶段。
相关是指指令之间存在着数据或指令依赖。
为了进一步提高指令流水线的性能,出现了指令流水线的多发技术。
超标量技术是通过设置多条指令流水线达到并行执行多条指令。
超流水技术是开发指令的时间并行性。
超长指令字技术是开发标量之间的随机并行性。