【学习笔记】微体系结构-单周期、多周期、流水线
前言
提示:多周期与多发射、多核不同。
单周期、多周期、流水线三者之间的演变过程如下图。
一、单周期
单周期微体系结构是在一个周期内执行整个指令(即CPI=1,每条指令需要耗费一个时钟周期),其周期时间受最慢的指令时间限制,单周期处理器还需要单独的DCache和ICache,因此,这种设计不具有实际意义。
单周期直通计算机的内核结构
此结构为最简单的,不考虑条件分支、跳转、信号增强等等。
接着我们考虑更详细的结构。
这个结构就可以进行条件分支、跳转、Load和Store操作等。具体的过程可以参见《计算机组成原理》Alan Clements。
寄存器-寄存器数据通路
寄存器-寄存器型是处理器执行的最简单的指令,下面介绍四种操作的数据通路。
1.Load操作
2.Store操作
3.跳转指令
4.条件分支
示例
以下面的指令为例,来源《Digital Design and Computer Architecture - RISCV Edition》
更详细的信息:
这个程序一直处于循环,不会跳出。
为下面叙述方便,书中假设寄存器x5最初包含值6,而x9包含0x2004。内存位置0x2000处包含值10。为节省篇幅,我们以 lw x6,-4(x9) 为例。
具体步骤:
- 从ICache中读取指令。
- 读取包含基地址的源寄存器。将指令中指定源寄存器的位直接连接到寄存器堆的A1中输入,将读取到的值存到RD1中。
- 读取偏移量。如果此偏移量存在符号值,处理器需要进行符号位扩展。在此例中,由 Extend Unit 执行此操作。
- 处理器将基地址与偏移量相加,找到要从内存中读取的地址。这一部分由 ALU 组件执行,数据来源于 2. 3. 步。
- 从 ALU 中处理过的内存地址输入至 DCache 的地址(A)端口。数据从 DCache 中读取到 ReadData 总线,然后在RegWrite 控制信号有效(=1)且到达时钟上沿(认为周期结束)时写回目标寄存器。其中,目标寄存器由指令中指定目标寄存器的位决定,本例中将这个信号输入寄存器堆的 A3 中。
- 计算下一条指令的地址 PC,同样在时钟上沿时写入程序计数器。
上述仅描述了单周期处理器的数据路径,将控制单元连接到数据路径后得到完整的单周期处理器结构。
控制单元也被称为控制器或译码器,将产生大部分的控制信号(主译码器)和确定ALU执行什么操作(ALU译码器)。
性能分析
我们考虑程序的执行时间
T
s
i
n
g
l
e
=
指令个数
∗
C
P
I
∗
T
c
−
s
i
n
g
l
e
T_{single}= 指令个数*CPI*T_{c-single}
Tsingle=指令个数∗CPI∗Tc−single
其中
T
c
−
s
i
n
g
l
e
=
t
p
c
q
P
C
+
2
t
m
e
m
+
t
R
F
r
e
a
d
+
t
A
L
U
+
t
m
u
x
+
t
R
F
s
e
t
u
p
T_{c-single}=t_{pcqPC}+2t_{mem}+t_{RFread}+t_{ALU}+t_{mux}+t_{RFsetup}
Tc−single=tpcqPC+2tmem+tRFread+tALU+tmux+tRFsetup
在大多数实现技术中,ALU、内存和寄存器堆比其他组合块慢得多,因此上面的公式是简化过的,但已经足够描述处理器的周期时间。
二、多周期
单周期处理器的缺点
- 需要单独的 ICache 和 DCache,大多数处理器只有一个外部存储器来存储数据和指令。
- 需要足够长的时钟周期来完成最慢的指令执行。
- 需要三个加法器(ALU+2*PC逻辑),这将显著的增加成本,毕竟加法器很贵。
多周期处理器的数据路径
多周期处理器将一条指令分成多个较短的步骤来解决这个缺点,具体如下图。
提出划分阶段的思想,将每一条指令拆分为 5 个阶段:IF(Instruction Fetch,指令获取),ID(Instruction Decode,指令解码),EX(Execution,指令执行),MEM(Memory Access,内存读写)和 WB(Write Back to Register,写回寄存器)。此时,CPI为N(在这里为5)。
依然以指令为单位,只不过一条指令被分为更细的几个阶段来执行,这样可以减少阶段数不同引起的单位指令执行时间的误差。
多周期处理器将组合存储器用于加载存储指令和数据,可以选择在一个周期读取指令,在另一个周期内读取或写入数据。首先,我们给出完整的多周期处理器结构图。
多周期不同于单周期的地方
- 在数据写回到寄存器堆时,并不是直接连接到寄存器堆WD3写入端,而是在结果总线上添加一个多路复用器,以便在将结果反馈回寄存器堆的写入数据端口(WD3)。
- 更新程序计数器时,由于将指令分成了不同阶段,因此在取指阶段,ALU 实际处于空闲状态,因此可以用 ALU 来进行PC更新的操作,然后将结果写入程序计数器。同样,分支预测在译码阶段计算分支预测的目标地址时,同样可以利用空闲的 ALU 进行计算,而不需要再添加一个加法器,可以减少硬件的复杂性。
注:在处理器中,对下一条指令的地址进行计算是在取指阶段就已经完成的,在更新PC阶段,一般只是将计算好的结果传给程序计数器。
接着,和单周期处理器一样,在数据路径的基础上,添加控制单元构成完整的多周期处理器。
多周期处理器的控制单元由Main FSM、ALU译码器和指令解译码器(Instr译码器)组成。
性能分析
平均
C
P
I
=
每条指令的加权
∗
该指令划分的阶段数
平均CPI=每条指令的加权*该指令划分的阶段数
平均CPI=每条指令的加权∗该指令划分的阶段数
T
c
−
m
u
l
t
i
=
t
p
c
q
+
t
d
e
c
+
2
t
m
u
x
+
max
{
t
A
L
U
,
t
m
e
m
}
+
t
s
e
t
u
p
T_{c-multi}=t_{pcq}+t_{dec}+2t_{mux}+\max\{t_{ALU},t_{mem}\}+t_{setup}
Tc−multi=tpcq+tdec+2tmux+max{tALU,tmem}+tsetup
T
s
i
n
g
l
e
=
指令个数
∗
平均
C
P
I
∗
T
c
−
m
u
l
t
i
T_{single}= 指令个数*平均CPI*T_{c-multi}
Tsingle=指令个数∗平均CPI∗Tc−multi
多周期微体系结构仍然用于廉价的微控制器,如8051、68HC11、,以及电器、玩具和电子产品中的PIC16系列。
流水线处理器
多周期处理器的缺点
- 在假设CPI和电路元件延迟的情况下,有很多例子表明多周期处理器比单周期处理器更慢。根本原因在于指令被分为多个步骤,但是多周期处理器的周期时间并没有提高相应的倍数。
- 与单周期处理器相比,他去除了单独存储指令和数据的存储器和两个加法器,但他还需要额外的五个寄存器和多路复用器 。
流水线处理器
将单周期的指令划分为多个阶段(比较基础的是五段流水,但并不是所有的处理器都会分为五段),利用指令重叠提高效率,这样五条指令就可以同时进行。流水线提高了指令级并行性(ILP),并且由于其成本效益,如今几乎所有处理器都在使用它。
接着可以给出流水线的抽象视图。
流水线系统的一个核心问题是当一条指令的结果在前一条指令完成之前而被后续指令使用时,如何处理发生的冒险。
流水线处理器的数据路径
简而言之,就是在单周期处理器中加入了流水线寄存器。
流水线处理器的控制路径
流水线处理器使用与单周期处理器相同的控制信号,因此具有相同的控制单元。
流水线冒险
1.数据冒险
当一条指令试图读取尚未被前一条指令写回的寄存器时,就会发生数据冒险。
解决方法
- 通过转发
需要在ALU前面添加多路复用器,以便从寄存器堆或访存或写回阶段选择其操作数,如图。
整个流水线处理器的结构图。
- 使用暂停解决数据冒险
如果前一个指令有两个及以上周期的延迟,则无法通过转发解决数据冒险,这个时候可以通过暂停解决。
注:通过流水线传播的未使用的阶段称为气泡,其行为类似于nop指令。气泡是通过在译码阶段停顿期间将执行阶段控制信号清零来引入的,因此气泡不执行任何操作并且不改变体系结构状态。
整个流水线处理器结构。
2.控制冒险
分支预测指令时,当取指发生时还没有决定下一步取什么指令时,就会发生控制冒险。
解决方法
- 暂停流水线直到分支预测指令做出决策,但这会严重影响 性能。
- 预测是否会执行分支,并根据预测开始执行指令,并在后来确定预测错误时刷新流水线来解决控制冒险。
能处理所有冒险的流水线处理器结构图
性能分析
平均
C
P
I
=
每条指令的加权
∗
该指令划分的阶段数
平均CPI=每条指令的加权*该指令划分的阶段数
平均CPI=每条指令的加权∗该指令划分的阶段数
T
s
i
n
g
l
e
=
指令个数
∗
平均
C
P
I
∗
T
c
_
p
i
p
e
l
i
n
e
d
T_{single}= 指令个数*平均CPI*T_{c\_pipelined}
Tsingle=指令个数∗平均CPI∗Tc_pipelined
参考
1.https://blog.csdn.net/qq_42950838/article/details/113406943?spm=1001.2014.3001.5506
2.《计算机组成原理》Alan Clements
3.Digital Design and Computer Architecture - RISCV Edition