主页
文章
分类
系列
标签
简历
【计算机组成原理与体系架构02】流水线
发布于: 2023-2-6   更新于: 2023-2-6   收录于: 计算机组成原理与体系架构
文章字数: 75   阅读时间: 1 分钟   阅读量:

注:本文为读书笔记,并非原创内容,主要对阅读材料进行摘抄整合与内容梳理,参考资料已经在文末注明

单周期到流水线

单周期CPU的设计

下图是一个简单的CPU模型,

  • 程序计数器,又称PC,指示当前指令的地址;
  • 指令存储器,按照指令地址存储指令码,接收PC,读出指令;
  • 译码部件,用于分析指令,判定指令类别;
  • 通用寄存器堆,用于承载寄存器的值,绝大多数指令都需要读取及修改寄存器;
  • 运算器,用于执行指令所指示的运算操作;
  • 数据存储器,按照地址存储数据,主要用于访存指令。

数据通路上各组成要素间的具体连接规则如下: 根据PC从指令存储器中取出指令,然后是译码部件解析出相关控制信号,并读取通用寄存器堆;运算器对通用寄存器堆读出的操作数进行计算,得到计算指令的结果写回通用寄存器堆,或者得到访存指令的地址,或者得到转移指令的跳转目标;load指令访问数据存储器后,需要将结果写回通用寄存器堆。通用寄存器堆写入数据在计算结果和访存结果之间二选一。由于有控制流指令的存在,因此新指令的PC既可能等于顺序下一条指令的PC(当前指令PC加4),也可能来自转移指令计算出的跳转目标。 Pasted image 20230927164655|800|800

处理器的执行过程

  1. 复位信号将复位的PC装载到PC触发器内,之后的第一个时钟周期内,使用PC取指、译码、执行、读数据存储器、生成结果;
  2. 当第二个时钟周期上升沿到来时,根据时序逻辑的特性,将新的PC锁存,将上一个时钟周期的结果写入寄存器堆,执行可能的数据存储器写操作;
  3. 第二个时钟周期内,就可以执行第二条指令了,同样按照上面两步来执行。

由一系列指令构成的程序就在处理器中执行了。由于每条指令的执行基本在一拍内完成,因此这个模型被称为单周期处理器

流水线处理器

单周期处理器模型中,每个时钟周期必须完成取指、译码、读寄存器、执行、访存等很多组合逻辑工作,为了保证在下一个时钟上升沿到来之前准备好寄存器堆的写数据,需要将每个时钟周期的间隔拉长,导致处理器的主频无法提高。使用流水线技术可以提高处理器的主频。在引入流水线技术之前,先介绍一下多周期处理器的概念。

多周期处理器

多周期处理器的思路就是:通过减少每个时钟周期的工作量,从而缩短每个是周期的时长,从而提高处理器的主频

按照取指、译码并读寄存器、执行、访存和准备写回划分为5个阶段。如果我们在每段操作前后加上触发器,看起来就能减少每个时钟周期的工作量,提高处理器频率

物理硬件上如何支持呢,多周期处理器通过使用分频时钟,可以确保在同一条指令的后面几个时钟周期执行时,控制逻辑因没有接收到下一个时钟上升沿所以不会发生变化

Pasted image 20230927170537|800|800

  1. 在第1个时钟周期,通过PC取出指令,在第2个时钟上升沿锁存到指令码触发器R1;
  2. 在第2个时钟周期,将R1译码并生成控制逻辑,读取通用寄存器,读出结果在第3个时钟上升沿锁存到触发器R2;
  3. 在第3个时钟周期,使用控制逻辑和R2进行ALU运算。

Pasted image 20230927171012|800

从多周期的流水线

多周期处理器设计可以提高运行频率,但是每条指令的执行时间并不能降低 可以将各个执行阶段以流水方式组织起来,同一时刻不同指令的不同执行阶段重叠在一起,进一步提高CPU执行效率

从多周期处理器演进到流水线处理器,核心在于控制逻辑和数据通路对应关系维护机制的变化。多周期处理器通过使用分频时钟,可以确保在同一条指令的后面几个时钟周期执行时,控制逻辑因没有接收到下一个时钟上升沿所以不会发生变化。流水线处理器则通过另一个方法来保证这一点,就是在每级流水的触发器旁边,再添加一批用于存储控制逻辑的触发器。指令的控制逻辑藉由这些触发器沿着流水线逐级传递下去,从而保证了各阶段执行时使用的控制逻辑都是属于该指令的

Pasted image 20230927171315|800|800

Pasted image 20230927171322|800|800

指令相关和流水线冲突

流水线技术固然大幅度提高了CPU运行的效率,但是同样带来了更多挑战

问题的根源

先给出答案,指令相关性就是问题的根源

指令相关分为数据相关,控制相关,与结构相关

数据相关性与解决方案

数据相相关性分为 写后读(Read After Write,简称RAW):即后面指令要用到前面指令所写的数据,也称为真相关。在简单流水线会引起冲突; 写后写(Write After Write,简称WAW):两条指令写同一个单元,也称为输出相关。乱序执行中会引起流水线冲突; 读后写(Write After Read,简称WAR):后面的指令覆盖前面指令所读的单元,也称为反相关。乱序执行中会引起流水线冲突

一个会发生冲突的例子

Pasted image 20230927210328|800

采用阻塞的方式解决流水线冲突的思路

第1条指令的写回阶段指向第2条指令的译码阶段的箭头以及从第2条指令的写回阶段指向第3条指令的译码阶段的箭头都表示RAW相关会引起冲突。这是因为如果第2条指令要使用第1条指令写回到寄存器的结果,就必须保证第2条指令读取寄存器的时候第1条指令的结果已经写回到寄存器中了,而现有的5级流水线结构如果不加控制,第2条指令就会在第1条指令写回寄存器之前读取寄存器,从而引发数据错误。为了保证执行的正确,==一种最直接的解决方式是让第2条指令在译码阶段等待(阻塞)3拍,直到第1条指令将结果写入寄存器后才能读取寄存器==,进入后续的执行阶段。同样的方式亦适用于第2、3条指令之间和第3、4条指令之间

解决方案: 采用阻塞解决数据相关的流水线

Pasted image 20230927210501|800|800

流水线前递出技术

采用阻塞的方式虽然能够解决RAW相关所引发的流水线冲突,但是阻塞势必引起流水线执行效率的降低。

流水线前递技术是通过直接将第一条指令的计算结果直接拿来用,而不等待它先存入寄存器。

具体实现的方法是,在流水线中读取指令源操作数的地方通过多路选择器直接把前面指令的运算结果作为后面指令的输入。考虑到加法指令在执行级就完成了运算,因此能够设计一条通路,将这个结果前递至读寄存器的地方,即有一条从执行级到译码级的前递通路。除此之外,还可以依次添加从访存级、写回级到译码级的前递通路

Pasted image 20230927211125|800|800

简而言之,别存了,拿来吧你( •̀ ω •́ )✧

控制相关引发冲突及解决方法

控制相关引发的冲突本质上是对程序计数器PC的冲突访问引起的

一个发生控制冲突的例子

Pasted image 20230927211516|800|800

阻塞方法解决控制冲突

执行阶段R2触发器所存储的值经过计算之后才能给出转移指令的正确目标并在下一个时钟上升沿更新PC,但是图中转移指令尚未执行结束时,PC已经更新完毕并取指了,从而可能导致取回了错误的指令。为了解决这个问题,可以通过在取指阶段引入2拍的流水线阻塞来解决

Pasted image 20230927214321|800

转移指令的延迟槽技术

在定义指令系统的时候就明确转移指令延迟槽指令的执行不依赖于转移指令的结果,这样转移指令后面的指令在取指阶段1拍也不用等。总之,在单发射5级静态流水线处理器中,通过在译码阶段对转移指令进行处理和利用转移指令延迟槽技术,就可以避免控制相关引起的流水线阻塞

结构相关引发冲突及解决方法

结构相关引起冲突的原因是两条指令要同时访问流水线中的同一个功能部件

解决方案: 阻塞流水线 + 增加资源


[1] 《计算机体系结构基础》