计算机组成原理第五章 您所在的位置:网站首页 常见的计算机硬件有哪些中央处理器 计算机组成原理第五章

计算机组成原理第五章

2024-07-17 15:41| 来源: 网络整理| 查看: 265

1.指令流水线 1.1 什么是指令流水线

在解释什么是指令流水线之前,我们需要清楚指令的真实执行过程,一个计算机对于多条指令的执行有以下的几种方式:

(1)串行执行:传统的冯诺依曼机是把指令一条一条的执行的,这被称为串行执行的执行方式,它设计起来很简单,也很好控制,但是处理器一次只能处理一个指令,导致速度很慢。如图所示(我们假设每一执行的阶段时间都是t,并且指令有n条): 在这里插入图片描述 (2)重叠执行:既然一次执行一条慢,于是我们就会想到既然一个指令可以被分为多个阶段(取指译码和执行),而每一个阶段执行时所需要的硬件不一样,那么我们为什么不把指令的各个阶段拆开来执行呢?也就是同时并行的执行多个指令的不同阶段(这其实在前面已经分析过一次),这样可以大大地节省时间,这就是重叠执行的思想。但是根据重叠的方法,还可以再细分: {1}一次重叠执行:前一条指令的执行阶段和后一条指令的取指阶段重叠: 在这里插入图片描述 第一次执行需要3t的时间,后面执行一次只需要2t。所以总的来说,减少了约3分之一的时间。但是缺点是,它需要额外的硬件来实现两个指令一同执行,开销更大(其实就是操作系统的临界区问题)。

{2}二次重叠: 这个不用多说了,更节约时间(同时可以执行三条指令),但是实现起来更加复杂: 在这里插入图片描述

=这种重叠执行指令的执行方式就是指令流水线!!! 实际上,指令流水线的执行不可能像图上这么流畅,因为不同指令的执行周期和取指周期还有译码阶段,它们的硬件是有可能发生冲突的,所以上面的是理想状态,现实中会比上面的理想状态实施起来慢(有冲突只能等),但是总是比串行执行要快的。 PS:这里只是把指令分成了3个阶段,但是指令其实可以分成许多阶段(你甚至可以规定一个节拍就一个阶段),然后就可以同时让多条指令并行执行。考试最常考5个阶段的指令,这个后面说。

1.2 时空图

这是一个考试常见的图,它是用于表现指令流程线一个常用的画法: 在这里插入图片描述 图中的横坐标是时间,纵坐标是执行到了什么阶段,纵坐标有几个就代表题目把执行过程分成了几个阶段。 图中的 I 1 , I 2 . . . I_1,I_2... I1​,I2​...等就是指令的序号。从图中还可以看出它的指令流水线采用了三次重叠的执行方式。时空图的重点是可以帮助我们计算指令流水线的性能,这需要先学习一下指令流水线的性能指标。

1.3 指令流水线的性能指标

有三个指标: (1)吞吐率(TP):单位时间内,流水线可以完成多少条指令。 设一共要执行n条指令,执行完需要 T k T_k Tk​的时间,那么: T P = n T k TP = \frac{n}{T_k} TP=Tk​n​ 现在用这个理想状态下的时空图为例子: 在这里插入图片描述 T P = n ( k + n − 1 ) Δ t TP=\frac{n}{(k+n-1)\Delta t} TP=(k+n−1)Δtn​如果我们的指令无限多也就是n趋近于无穷时: T P = 1 Δ t TP=\frac{1}{\Delta t} TP=Δt1​。其中, Δ t \Delta t Δt是执行一个指令的阶段所需要的时间(常常就是一个时钟节拍,因为都探讨极限理想了)。这里其实还给出了,n-1次重叠执行,所需要的时间,正好是 ( k + n − 1 ) Δ t (k+n-1)\Delta t (k+n−1)Δt。 这里再引入一个装入时间和排空时间的概念,其实就是从第一条指令执行到它执行结束的部分还有最后一条指令执行开始到结束的部分,从图上看正好像是一点点装进去又一点点排空。 在这里插入图片描述 这两个时间段使得硬件被一点点全部启动,然后一点点全部关闭。

(2)加速比S:完成同样的一批任务,不使用指令流水线和使用指令流水线所需要的时间比值。 说白了,就是和冯诺伊曼的串行执行相比,效率提高了多少。其实,用上面的例子去算,串行执行需要 n k Δ t nk\Delta t nkΔt的时间,所以 S = n k k + n − 1 S=\frac{nk}{k+n-1} S=k+n−1nk​。显然,S的值越大越好(n越大它就越大)。n趋近于无穷的时候,加速比为k,所以极限情况下(指令足够多),分几个阶段就快了几倍。

(3)效率E:流水线设备的利用率。 计算方法其实就是计算整个时空图实体的面积(正好可以拼接成一个长方形)比上整个时空图的面积(就是一个大长方形)。 在这里插入图片描述 其实从图上可以看出,高固定是k,长就是 ( k + n − 1 ) Δ t (k+n-1)\Delta t (k+n−1)Δt,所以可以得出效率公式: E = k [ ( k + n − 1 ) − ( k − 1 ) ] Δ t k ( k − 1 ) Δ t = n k + n − 1 E=\frac{k[(k+n-1)-(k-1)]\Delta t}{k(k-1)\Delta t}=\frac{n}{k+n-1} E=k(k−1)Δtk[(k+n−1)−(k−1)]Δt​=k+n−1n​ 因为k是常数,所以很显然,n足够多的时候,这个值可以趋近于1,也就是利用率到了百分百。

从三个性能指标来看,当指令足够多的时候,叠的越多越好。当然这是理想状态,即每一个指令的执行时间相同且运行结束时,下一条指令立即衔接。

1.4 指令分段–五段式指令流水线(选择大题都必考)

前面把指令分为了三段,现在进一步的扩展,把指令扩展成五段,这其实也是最常用的分段方法。这五段如图所示: 在这里插入图片描述 (1)取指令阶段IF。(2)指令译码阶段ID。(3)指令的执行阶段EX。(4)访存阶段M。(5)把计算结果写回通用寄存器WB。 这种五段式的指令,是由世界上第一个RISC指令集MIPS提出的(AMR是后期提出的)。要注意的是,这五个阶段是必须的,也就是说,即便有的指令没有后面两个阶段,计算机也会认为它们在执行(因为如果要认真的区分,设计起来会很复杂)。现实中每一个阶段用的时间是不一致的,但是设计的时候,为了方便实现,通常会把每一个阶段的时间设置成一样的,也就是用最长的那个阶段的时间作为全部的总时间。 (其实,只要是RISC指令集,都是这样设计的,因为指令短,花费这点时间来简化设计没有什么)。所以每一条指令的机器周期数相同,长度也相同才能更好的实现指令流水线。 因为每一个阶段的时间不同,那么一开始就肯定会存在空闲的时候(比如M只需要70ns,但是时间需要100ns,那么前30ns空闲),但是我们却知道因为要并行的运行许多指令,所以前一个阶段产生的数据不能一直占用寄存器,所以就会在每一个阶段后面加一个缓冲寄存器(图中ID后面的A和B还有Imm,EX后面的空白还有上面的store),这个缓冲寄存器也被称为锁存器。锁存器的功能就是保留本流水段的执行结果给下一流水段使用。

其次,图上出现了好久没有见到的Cache,这里就可以对Cache进行补充:如图所示,其实取指阶段和访存阶段往往访问的是Cahe,不是主存(回顾第三章)。然后图上也指明了,我们的Cache可以分成两个部分,一部分专门用来存指令,叫做指令Cahce,另一部分则用于存数据,称为数据Cache。而且这两个Cache其实是分成两半的,每一个都是一个单独的元件,这就导致它们可以并行的运行。 如果Cache不命中,则就必须花费更多的时间去访问主存,因为很耗费时间,所以指令流水线会因此出现断流(全停下来等)。

最后,我们需要注意的是,图上ALU在计算前数据都到了寄存器里面(然后存到AB锁存器里面),这是因为RISC指令集的运算必须两个数都在寄存器中,不能像CISC那样一个在寄存器一个在主存。 AB就是专门用来存放两个运算数的,上面的Imm锁存器则是用于存放立即数的。 M阶段后面的最小的框其实是一个寄存器,因为运算结果也可能是存入寄存器的(最后也可能像图上那样回流到通用寄存器里)。

1.5 影响流水线的因素

(1)结构相关(指令之间的资源冲突)。 其实就是操作系统的互斥问题。比如,两条指令一个是取指阶段,一个是执行阶段,它们如果Cache未命中的话,就需要同时访问主存,引发冲突。同时,也会出现多条指令争抢同一个寄存器的现象。解决方法有: 1.后一条指令先暂停一个周期再运行。2.资源重复配置:即把资源分到不同的存储体中。 比如前面说的,把指令Cache和数据Cache分开来单独的设计。第一种容易实现,第二种效率更高。

(2)数据相关(它是重点考点)(后一条指令的执行可能需要前一条指令执行结束之后才获得)。其实就是操作系统的同步。解决方法:1.一直等待,直到需要的指令执行完成为止,可以通过硬件的阻塞(stall)[也被称为插入气泡]和软件插入"NOP"实现,其实就是指插入1到几个周期的空指令来等待。2.转发机制(数据旁路技术): 这个技术要更复杂一些,比如我们要计算 a=1+2,b=a-1。按照方法1,第二条减法指令需要等待第一条指令完全执行完第五个周期才可以,但是其实第一条指令在执行完执行阶段就已经有a的值了,所以就连接一条线到第二条指令,在第一条指令执行出a的结果以后,第二条指令立即开始执行,这样就可以少等待2个周期,但是会麻烦一些。3.编译优化:就是先执行后面的,不涉及到前一条指令的指令,然后等前面指令结果出来再继续执行,这其实是编译原理的知识不用深究,感兴趣可以看看。

(3)控制冲突。控制冲突是因为转移指令或者其他可以改变PC的情况(比如中断),打断了原本的指令执行顺序造成的(因为指令流水线实现的基础就是顺序的执行指令)。关键的是,转移指令只有在执行到第五个阶段结束你才知道需要转移,而这个时候下面的四条指令都已经开始执行了!解决办法:1.提前预测是否会跳转,又分为简单预测和动态预测两种,简单预测就是看到jmp指令,译码器就认为会跳转或者不会跳转(通常是全认为会跳转),动态预测就是额外加个硬件,多判断一下会不会跳转(因为硬件很简单,预测的也不是那么准确,它的原理一般就是根据历史情况,如果前面跳转的多,那就预测会跳转,少就不会,其实就是一个计数器)****。虽然动态预测很简单,但是准确率确实比简单预测要高一些。2.预取转移成功和转移失败两个方向上的目标指令: 这需要额外的加两个指令寄存器什么的,原理就是同时把转移成功和失败的指令都并行运行,例如jmp指令的第一阶段结束以后运行jmp成功的第一条,jmp指令第二阶段结束以后就运行jmp失败的第一条,这样最后总是有的指令是可以继续运行的不需要移除全部。3.加快和提前形成条件码:和第二章学习的全加器是一样的,因为转移的条件不一定需要计算出来才知道,我们可以连上额外的硬件,提前就计算出是否需要转移(说的玄乎其乎的,其实就是在第三个阶段执行结果出来以后立即判断是否转移,不等指令走后面两个阶段了,其实和数据相关的转发机制也很类似)。4.提高转移方向的猜准率: 其实还是第一种方法里面的动态预测,只不过用更好的算法来预测,但是算法更复杂也意味着更大的计算开销。

1.6 流水线的分类 1.6.1 根据流水线使用的级别不同进行分类

(1)部件功能级流水线:就是对每一个部件(比如ALU算术逻辑单元)再进行细分,然后让各个部分并行的完成操作。举个例子: 在一次加法操作中,ALU需要完成求阶差,对阶,尾数相加和结果规格化四个过程,其中,不同的过程用到的子操作元件不同,所以可以并行的执行。ps:因为它们是在一个指令里面发生的,所以不是指令流水线,是部件流水线(计组常见的,研究好一套理论以后到处用)。 (2)处理机级流水线:就是上面介绍的指令流水线,把指令分成5段,然后并行执行。 (3)处理机间的流水线:如果有多个处理器(可以理解成多核),那么就可以实现更多的指令并行执行,比如前面说的互斥的指令。也可以实现第一个处理器完成取指阶段,然后递交到处理机间的公共存储器,交给第二个处理器去完成第二阶段…

1.6.2 按照流水线能完成的功能划分

(1)单功能流水线:只能实现单一功能的流水线。比如要搞个连续加法的时候,我么就可以搞一个加法流水线,快速执行。 (2)多功能流水线:就是可以同时搞多种功能的流水线,比如同时加法和乘法等。

1.6.3 按照连接方式分

(1)静态流水线:同一时间内,只能完成同一种功能(比如只能执行加法)。 (2)动态流水线:同一时间内,可以执行多种运算。其实和按照能完成的功能分没有太大区别,只不过一个强调干了什么,一个强调时间而已。

1.6.4 是否有反馈信号

(1)线性流水线:执行完当前指令就下一条,中间不存在对下面指令的反馈信号。 (2)非线性流水线:执行结束或者过程中对其他指令有反馈信号(最上面的图中就是,执行完成的结果最终还能回到译码阶段的寄存器中)。包括某些功能段会数次通过流水线(比如乘法是多次加法来实现的)。

1.7 流水线的多发技术 1.7.1 超标量技术

其实就是多核运行的模式: 在这里插入图片描述 如图所示,就是一次可以同时运行多条指令的同一个阶段,它的特点是不能随便改指令的顺序,同时还要充分考虑互斥和同步问题,对编译器的要求很高。 图中流水线速度快了3倍。

1.7.2 超流水技术

它不需要多核来支持,它的原理如图: 在这里插入图片描述 不需要等待上一条指令的一个阶段执行完,就可以执行下一条指令。也就是一个时钟周期内,一个功能部件被使用多次。但是对编译设计人员的要求再次增加。图上的流水线速度也快了三倍。

1.7.3 超长指令字

在这里插入图片描述 说实话,这个不太好理解。基本原理是这样的:一些指令的执行操作可能会占用不同的部件,那么计算机就会把这些指令给合并成一条大指令,然后执行到执行阶段就全部并行的执行,这样一次就可以执行完很多指令。 它也是由编译器来完成的,因为操作码和地址码都合并了,所以指令会很长很长,所以叫超长指令字。同时,它必须有多个处理器才能实现(因为要一起取数据,一起执行,那需要多个MDR和MAR)。

1.8 考查指令流水线时,常考的几个指令

一共有五个:运算类指令,LOAD指令,STORE指令,条件转移指令和无条件转移指令。其中,只有取数指令LOAD和存数指令STORE才需要访问主存。

1.8.1 运算类指令 指令名称汇编语言功能加法指令(寄存器和寄存器)ADD R s , R d R_s, R_d Rs​,Rd​ ( R s ) + ( R d ) → R d (R_s)+(R_d)\rightarrow R_d (Rs​)+(Rd​)→Rd​加法指令(寄存器和立即数)ADD #666 , R d ,R_d ,Rd​ 666 + ( R d ) → R d 666+(R_d)\rightarrow R_d 666+(Rd​)→Rd​算术左移SHL R d R_d Rd​ ( R d ) < < < 2 → R d (R_d)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有