指令通常存储在主存中,默认情况下由程序计数器进行依次读取,除非遇到 JMP 命令才会进行跳转继续执行。而 执行一条指令的过程一般如下( 结合图片进行理解 ):
①先根据程序计数器 PC 的值从存储器 M 中读取一条指令,然后送到指令寄存器 IR 中;
②指令寄存器 IR 将指令中的操作码 OP 送到指令译码器 ID 中进行译码,再送给时序发生器和操作控制器 OC 决定执行什么操作;( 注:一条指令由操作码 OP 和地址码 A 构成 )
③然后指令寄存器 IR 将指令中的地址码 A 送给地址寄存器 AR ,同时使程序计数器 PC 的值加1,即指向下一个指令;
④存储器 M 根据地址寄存器 AR 中的地址找到对应的某个存储单元,然后将该存储单元的数据送给数据寄存器 DR;
⑤然后再将数据寄存器 DR 中的数据送给通用寄存器组,这里采用通用寄存器组是考虑到了多个操作数时的情况,方便进行加减乘除、存数等情况。通用寄存器组里的数据再根据不同的指令决定是进行直接输出还是通过算术逻辑单元 ALU 进行运算。
⑥所得的结果状态反映到状态条件寄存器 PSWR 中,如结果为0有零标志位,有产生进位就有进位标志等。
可以看到,上面所描述的一条指令的执行过程还是比较繁琐的。其中非流水线的指令便是按照上面的执行过程,每执行完一条指令之后才能执行下一条指令,如下图所示:
而采用流水线的指令则是 将上述的指令执行过程分为了 取指、分析( 译码 )、执行 3个子过程 。( 有些教材会分为 取值、译码、执行、存数 4个子过程 )。在采用流水线的指令中,每完成一条指令的一个子过程,则立即开始下一条指令的该子过程,如下图所示 :
该流水线指令我们称为 标量流水线指令,其中还有一种流水线指令叫做超标量流水线指令( 即同一个时间可执行两条及两条以上指令的某个子过程 ),也是蕴含了多个知识点,这里软考不考,所以略过,有时间再写博客。
okay,认识完流水线指令,接下来我们再来认识一下有关流水线的相关计算公式。
一条指令的开始到下一条指令的最晚开始时间,这段时间间隔我们称为流水线的周期。因为在流水线中,指令的执行过程被分为了 取指、分析、执行 3个子过程,这三个子过程有各自的执行时间,一般我们 取执行时间最长的一段作为流水线的周期。如 取指需要 4 ns ,分析需要 3 ns,执行需要 2 ns ,则 流水线周期 △t 等于 4 ns 。
当我们要计算多条指令的执行时间 tm 时,它的值等于 “ 一条指令的执行时间 + ( 指令条数 - 1 ) * 流水线周期 ”,举个例子,如下图所示 :
在该图中,取指和分析都是1个单位时间,而执行是2个单位时间,当我们计算三条指令的执行时间时,只需要计算一条指令的完整执行时间再加上 2个流水线周期即可。
而在实际计算中,多条指令的执行时间又分为理论执行时间和实践执行时间,题目没特别说明,一般采用理论执行时间计算即可。
①理论时间是指当子过程之间的时间不一样时,子过程之间是无缝衔接执行的。
理论公式 : tm = ( t1 + t2 + … + tk ) + ( n - 1 ) * △t
②实践时间是指当子过程之间的时间不一样时,子过程之间必然有一定的空白时间依次进行的。
实践公式 : tm = ( k + n - 1 ) * △t
流水线的吞吐率 TP 是指在单位时间内流水线所完成的任务数量或输出的结果数量。所以它的值就等于以下公式:
可以看到,当流水线的执行时间一定时,指令条数越多,吞吐率也越大。当指令的条数趋于无穷大时,我们便可以得到流水线的 最大吞吐率 TPmax 。
流水线的加速比 S 是用来衡量流水线好坏的重要指标,当采用的指令及其条数相同时,其值等于不使用流水线时的执行时间除以使用流水线的执行时间。
可以看到 当 S 的值越大时,则流水线的执行时间越短,该流水线越好。
综合上述知识,请试着解决下列问题:
若指令采用流水线,一条指令的执行过程分为 取指、译码、执行 3个子过程,其中取指需要 2 ns,译码需要 2 ns,执行需要 3 ns,则流水线的周期为多少?执行100条指令需要多少时间?其吞吐率和最大吞吐率分别是多少?加速比的值又等于多少呢?
答案:3 ns ; 304 ns ; 0.33 ; 0.33 ; 2.30
流水线的效率 E 是指采用流水线时设备的利用率。其中设备可以分为 S1、S2、S3、S4 等模块。其时空图如下所示 (采用 S1、S2、S3 都为 △t,S4 为 3△t 举例):
其计算公式如下:
其实流水线的效率就是有颜色的部分在整个时空区的占比。在上述的时空图中 E = ( ( △t + △t + △t + 3△t ) × 3 ) / ( 12△t × 4) = 37.5%
备注 : 时空图这一块涉及到了操作系统知识,博主这一块暂未学到,只能先套用公式了,如果有更详细的解读,欢迎大家交流学习!如有错误,欢迎指正!