15 指令周期和流水线

图片来源:南京大学软件学院COA课程PPT

©author:zzb

15 指令周期和指令流水线

image-20211212172556900

指令周期

指令周期

image-20211212172643616

只有机器关闭,发生错误,遇到停止计算机的指令时,程序才会停止。只要计算机开着,即使不使用,也是持续在执行指令的

image-20211212172844488

返回字符串或向量数据是指比如要取一个字符串,那么一次可能无法全部得到,那么就必须要分多次,多次的计算源操作地址,取字符串,计算目的操作数地址,存字符串。但这是一条指令的功能,所以直到全部取完后,才进行下一条指令的地址计算

带中断的指令周期

image-20211212173408972

在这条指令执行完,下一条指令未开始的中间进行中断的判断(这时候PC已经是下一条指令的地址了)

image-20211212173517551

间址周期

image-20211212173634159

把间接地址的读取看作一个额外的指令子周期,相比于直接寻址,多了存储器的访问,所以单独作为一个子周期

image-20211212173845638

CPU的任务

image-20211212174036530

寄存器

image-20211212174727688

数据流

取指周期

image-20211212174908311

如果是同步的总线,那么只要按时间取做上面的流程即可,如果是异步总线,那么在存储器把数据放到数据总线上时,还要通过控制总线告诉CPU已经好了,所以存储器与控制总线之间是双向箭头。

而这里单向箭头,说明是同步总线。事实上,一般来说,CPU和存储器之间都是采用同步的

image-20211212175521345

黄色箭头代表两个含义:

  1. 控制PC传输地址,从而取指令

  2. 当指令取完后、指令执行前(一般是要取到IR中后才加1,即在取指周期的最后加1,否则不知道+1是加多少),而不是指令执行完,控制PC+1。但其实也不一定,如下,PC+1可以和其他的一起执行

    image-20220107160454915

间址周期

image-20211212175802748

image-20211212175852485

注意:间址周期取回来到MBR的只是有效地址EA,而通过有效地址EA去取操作数的过程是在执行周期里的

中断周期

image-20211212180314902

这里数据线都是指向存储器的,表明写操作,同时PC连到MBR,因此这里想要做的是对PC进行保存(PC这时候存的是下一条指令的地址),从而能够在中断之后能够准确的返回

中断中由控制器去告诉MAR地址,即PC要存储在存储器的哪一个位置,这个地址很可能是栈的指针,中断也是过程调用

(在取指过程中由PC告诉MAR,在间址过程中由MBR告诉MAR)

image-20211212181013832

指令流水线

image-20211212195915496

流水线可以让每个部件各司其职,只做它要做的单一的事,提高效率,节省时间

CPU就像一个生产线,如果各个步骤的任务分配不够好,比如不同步骤所需时间不同,那么就会造成资源的浪费,如矿泉水的生产,不同步骤时间不同,那么时间短的就会闲着。

因此对CPU生产线上的步骤进行阶段划分:

两阶段方法

image-20211212200713610

image-20211212200819371

取指令要访问内存,执行指令也可能要访问内存,可能会造成访存冲突

  • 取指令的等待是执行的时间比取指令的时间长,所以要等待

  • 执行阶段的等待是可能执行的是跳转指令,所以取指令在执行期间取好的指令就要作废,要根据新的地址去取指令,此时执行阶段要等待

六阶段方法

image-20211212201501405

六个阶段的所需时间几乎相等,因此如下可以把每个阶段所需时间当作一个时间单位

注意在EI阶段就会把目的操作数写入目的位置(主要是CPU内的寄存器),而如果是要写入主存的,才在WO阶段写,就和上面的FO一样,对于寄存器中的值不需要取,取的是主存中的操作数

image-20211212201648969

如同生产矿泉水的流水线

image-20211212201926683

  • 为了简化流水线的设计,可以假定每个指令都是6个阶段,如果没有某个阶段,不执行即可(如果为特殊指令设计不同阶段,那么是非常不划算的)

  • 阶段之间不一定全都能并行,如对内存的访问,会产生访存冲突

  • 几乎相等,仍然是有差别时间,那么会导致一定的等待,所以时间单位应该以最长的时间的为准,保证每个阶段在这个时间单位内都能执行完

image-20211212203056479

限制:在两阶段中跳转指令会使得已经取得的下一条指令失效。而在六阶段中会使得上面红框中执行了一半的指令的全部失效

注意:上面的最后一个指令的WO的同时,下面的FI也在执行,这是因为跳转指令不需要写存储器,而是在EI执行指令的过程中就把PC寄存器的值给改变了,所以在EI后面一个单位时间会执行正确的FI

image-20211212203319302

和跳转一样,中断也会使得指令失效,如上图中的排空流水线,这里多了一个无条件转移,那么在无条件转移把PC值修改后的一个单位时间内的FI才是有效的,中间的流水线全部失效,但已经在执行的指令的后续阶段是不受影响的

image-20211212203406279

绿色框是导致空闲的区域,而红色框内的执行是无效的,同理指令13的EI修改了PC,所以下面一个单位时间的I15才是有效的,中间的全部失效,但I13剩下的阶段正常进行

流水线的性能

image-20211212203637784

这里的t即单位时间,应当为各阶段中花费时间最大的时间,加上两阶段切换的时间

锁存时间是在两个阶段之间切换的时间就像接力赛,接力棒由前一个人放到桌子上,下一个人再去桌子上拿,这样是最稳妥安全的。

image-20211212204131466

Tk,n最理想的情况,第一条指令执行需要kt,后面的每多一条指令,总时间只增加1t,所以是$[k+(n-1)]t$

加速比是指没有使用流水线和使用了流水线的时间之比,是一个大于1的数(所以才叫加速比)

注意:其中分子没有使用流水线是固定的就是$nkt$,n条指令,每个需要kt时间,而分母使用了流水线的可能会有跳转的情况,会导致时间的改变

image-20211212204913493

image-20211212204955419

流水线中的阶段增多时,刚开始是会加快执行速度,但不是越多越好,当阶段太多,锁存延时会增加,增大开销。同时阶段越多,对硬件的使用冲突就会越大,需要更为复杂的控制逻辑

冒险(Hazard)

image-20211212192410033

结构冒险

硬件资源冲突

image-20211212192529705

分时使用如在时钟的上升沿和下降沿分给不同指令使用

数据冒险

image-20211212192825027

第一条指令中r1寄存器被更新,但根据指令的周期,后面的若干条指令中获得的r1寄存器都是未更新的

image-20211212193228583

软件nop指令让这3个时钟周期啥也不干,直到r1被成功更新后再执行后续指令,从而不需要改动硬件

image-20211212193309257

插入气泡——即硬件通过阻塞阻止可能出问题的指令的执行,因此需要判断哪些指令相关,怎么去阻塞的问题,虽然没有加nop指令,但在判断处理过程中也会有时间开销

image-20211212193513871

把需要的结果从中间就取过来,而不必去等指令的完全执行。

如r1要存放的新数据在经过ALU时即已经产生,只是结果没有更新到所在的r1寄存器中。此时第二条指令可以把这个结果取过来直接用,而不必等待第一条指令完全执行完。因为ALU不会同时被两条指令占用,第一条用完ALU,才会给第二条使用,因此上面的取中间结果是可行的

这就是转发/旁路当后面要用到的数据是前面算出来的经过ALU即可得到时,这时候旁路很有效,当不是时,旁路无法解决,如下

image-20211212194118012

r1寄存器此时要从内存中加载数据,而下面sub r1就要用这个数据进行alu计算,但数据还没有从内存中读取过来,所以必须要等待到从内存中取到数据才行,根据转发机制,同样不必等待这个数据加载到r1即可取到。即上面的红线的

解决办法就是交换指令的顺序,如右,lw b 和lw c到两个寄存器中,当执行add时,还没加载好,所以要等待。因此可以通过把下面的一条不相关的指令换上来,这样可以把等待的时间变成执行后面指令的时间总体执行时间会缩短

控制冒险

image-20211212194833356

当指令的执行顺序被改变,那么就会出现一部分的指令执行白处理了,原因就是取错了。

image-20211212195029198

即把跳转指令之后的指令和跳转到的指令都取过来,因为不知道这个跳转指令是不是真的要跳转(如多个条件跳转指令),所以就不能确定到底是执行后面的指令还是执行跳转指令中的指令

所以把两个都取过来,两条流水线处理,那么就保证了流水线的正常运行,即使有一条是失效的,那么不管它即可,另外一条在按照流水线正常运行

image-20211212195049933

预测会不会发生转移,如果预测会发生转移,那么就直接取跳转指令中指出的指令,而不去取跳转指令后面的指令。

如果预测失败了,那么就造成了流水线中已经执行的部分指令的失效;反之如果预测成功了,那么就避免了指令的失效,从而提高了流水线的效率

静态预测是和当前状态没有关系的,不会去根据刚刚处理的历史来改变,仅仅是按照规则

动态预测

image-20211212195529046

根据状态来动态预测

image-20211212195749976

遇到条件分支,看是不是第一次遇到,如果是就加入表中,如果发生过,看前面的预测是怎么样的,然后根据现在的状态来调整

  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
  • Copyrights © 2022-2024 zzb
  • RZ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信