一.指令集结构
1.基本知识
一个指令的组成 = 操作码 + 寻址方式 + 操作数 → 指令由CPU直接执行
操作码:一些操作的编码
寻址方式:访问寄存器或存储器的方法
操作数:存储单元的地址
指令集系统可以说是硬件与操作系统之间的桥梁
2.分类
RISC和CISC指令集
RISC:最著名的ARM指令集,固定长度指令集
CISC:X86指令集,可变长度指令集
3.寻址方式
1) 寄存器寻址
Add R4, R3
Regs[R4] <- Regs[R4] + Regs[R3]
R3寄存器中的值与R4寄存器中的值相加,并将结果存储在R4寄存器中
2)偏移寻址
Add R4, 100(R1)
Regs[R4] <- Regs[R4] + Mem[100 + Regs[R3]]
R3寄存器中保存的是某一个地址,100是偏移量
3)寄存器间接寻址
Add R4, (R1)
Regs[R4] <- Regs[R4] + Mem[Regs[R1]]
可以看作偏移寻址的一个特例
4)索引寻址
Add R3, (R1 + R2)
Regs[R3] <- Regs[R3] + Mem[Regs[R1] + Regs[R2]]
R1和R2寄存器的值是两个地址
5)直接寻址
Add R1, (1000)
Regs[R3] <- Regs[R3] + Mem[1000]
1000是立即数,表示这个位置的地址是1000,在存储器中取出地址1000所指向的值,与R3寄存器
中的值相加,把结果存储在R3中
6)自增寻址
Add R1, (R2)+
Regs[R1] <- Regs[R1] + Mem[Regs[R2]]
Regs[R2] <- Regs[R2] + d
RISC指令集功能设计原则:
1.从CISC中选取使用频率最高的指令,并补充一些最有用的指令
2.每条指令功能应尽可能简单,并在一个机器周期内完成
3.所有指令长度相同
4.只有load,store两个指令访问存储器,其余指令只能访问寄存器
5,简单高效支持高级语言
二.MIPS指令集结构
1.基本知识
1)具有一个简单的load/store指令集
2)注重指令流水效率
3)简化了指令的译码
4)高效支持编译器
5)32个32位通用寄存器,32个32位浮点寄存器
6)支持的寻址方式:寄存器寻址,立即数寻址,偏移寻址,寄存器间接寻址
2.指令格式
1)I类型
6 5 5 16
操作码 RS1 RS2 立即数
RS2 <- RS1 OP 立即数
数据的载入和存储
2)R类型
6 5 5 5 11
操作码 RS1 RS2 RD FUNC
RD <- RS1 FUNC RS2
函数对数据的操作
3)J类型
6 26
操作码 与PC相加的偏移量
用于跳转,返回,系统陷入
3.操作类型
几种符号标记:
<- 数据传送操作
R
e
g
s
[
R
4
]
0
Regs[R4]_0
Regs[R4]0 表示选择寄存器R4中内容的符号位(第零位)
R
e
g
s
[
R
4
]
0
Regs[R4]_0
Regs[R4]0 表示选择寄存器R4中内容的符号位(第零位)
R
e
g
s
[
R
4
]
24..31
Regs[R4]_{24..31}
Regs[R4]24..31 表示选择寄存器R4中内容的24位到31位
0
24
0^{24}
024 得到一个24位全零的一个值,用于符号扩展
“##” 拼接运算符
如:
R
e
g
s
[
R
1
]
16...31
<
−
(
M
e
m
[
R
e
g
s
[
R
8
]
]
0
)
8
#
#
M
e
m
[
R
e
g
s
[
R
8
]
]
0...7
Regs[R1]_{16...31} <- (Mem[Regs[R8]]_0)^8 \#\# Mem[Regs[R8]] _{0...7}
Regs[R1]16...31<−(Mem[Regs[R8]]0)8##Mem[Regs[R8]]0...7
表示R8所指的寄存器内容为地址的存储器的内容的符号位扩展到8位,然后拼接上R8寄存器所指的内容为地址的存储器内容的前8位
三.流水线结构
1.基本概念
将一个时序过程分解为若干的子过程,而且这些子过程可以并行执行的技术
虽然流水线技术并没有提高单个指令的执行速度,但增加了整个系统的吞吐率。
2.流水线的分类
有五种分类方法:
静态流水线
动态流水线
单功能的
多功能的
部件级的(处理基本运算操作)
处理机级的(指令流水线)
处理机间的(宏流水线)
线性的
非线性的(在线性基础上加反馈的)
标量处理机
向量处理机
3. MIPS流水线
MIPS指令流水线分为五个阶段:
----取指
----指令译码/读寄存器周期
----执行指令
----存储器访问
----写回
下面是MIPS的数据通路图
下面逐条分析:
- 取指(IF)
根据PC值从寄存器中取出指令,送入指令寄存器IR,然后PC值增加4,这是的PC指向了下一条指令,将这条指令的地址放入临时寄存器NPC中。
I
R
<
−
M
e
m
[
P
C
]
IR <- Mem[PC]
IR<−Mem[PC]
N
P
C
<
−
P
C
+
4
NPC <- PC + 4
NPC<−PC+4
- 指令译码/读寄存器周期
读IR寄存器,按照寄存器号读取寄存器文件,并将读出的结果放入两个临时寄存器A,B中。同时对IR寄存器的低16位进行符号扩展,将扩展后的立即数保存在临时寄存器Imm中。
A
<
−
R
e
g
s
[
I
R
6...10
]
A <- Regs[IR_{6...10}]
A<−Regs[IR6...10]
B
<
−
R
e
g
s
[
I
R
11...15
]
B <- Regs[IR_{11...15}]
B<−Regs[IR11...15]
I
m
m
<
−
(
(
I
R
16
)
16
#
#
I
R
16..31
)
Imm<- ( (IR_{16})^{16} \#\# IR_{16..31})
Imm<−((IR16)16##IR16..31)
-
执行/有效地址计算周期(EX)
寄存器访问: ALU <- A + Imm
寄存器-寄存器ALU: ALU <- A op B
寄存器-寄存器ALU: ALU <- A op Imm
分支操作: ALU <- NPC + Imm
Cond <- (A op 0) -
访存/分支操作完成周期(MEM)
访存操作:
LOAD: LMD <- LMDMEM[ALU]
STORE: Mem[ALU] <- B
分支操作:
if (Cond)PC <- ALU
else
PC <- NPC
- 写回(WB)
寄存器-寄存器型ALU指令:
R e g s [ I R 16...20 ] < − A L U Regs[IR_{16...20}] <- ALU Regs[IR16...20]<−ALU
寄存器-寄存器型ALU指令:
R e g s [ I R 11...15 ] < − A L U Regs[IR_{11...15}] <- ALU Regs[IR11...15]<−ALU
寄存器-寄存器型ALU指令:
I m m < − ( ( I R 16 ) 16 # # I R 16..31 ) Imm<- ( (IR_{16})^{16} \#\# IR_{16..31}) Imm<−((IR16)16##IR16..31)
4. 流水线性能分析
(1)吞吐率
定义:单位时间内流水线完成的指令个数或输出的数据数量
设实际吞吐率TP,m段流水线,已经完成n个任务
最大吞吐率TPmax,指流水线达到稳定状态的吞吐率。
如果每段的流水线执行时间相同,设时间△t0:
T
P
m
a
x
=
1
/
△
t
0
TPmax = 1 / △t0
TPmax=1/△t0
如果各段时间不等,设最大的段执行时间t0,则
T
P
m
a
x
=
1
/
m
a
x
[
△
t
0
]
TPmax = 1 / max[△t0]
TPmax=1/max[△t0]
可以得出结论:流水线的最大吞吐率与流水线中执行时间最慢的一段时间有关,这一段成为流水线的瓶颈
消除瓶颈的方法:
-----细分瓶颈段
将耗时最长的段继续分段
-----重复设置瓶颈段
对这个瓶颈段重复并行的设置,如第一个周期进入第一个段,第二个周期
进入第二个段,依次类推
设置流水段3为瓶颈段
实际吞吐率
设各段执行时间相同△t0,完成时间
T
流
水
=
m
△
t
0
+
(
n
−
1
)
△
t
0
T_{流水} = m△t_0 + (n - 1) △t_0
T流水=m△t0+(n−1)△t0
T
P
=
n
/
T
流
水
TP = n / T_{流水}
TP=n/T流水
(2)加速比
定义:实现相同功能的流水线速度与非流水线速度的比
按照流水段的运行时间等长计算:
S
=
T
非
流
水
/
T
流
水
S = T_{非流水} / T_{流水}
S=T非流水/T流水
T 非 流 水 = m n △ t 0 T_{非流水} = mn△t_0 T非流水=mn△t0
T 流 水 = m △ t 0 + ( n − 1 ) △ t 0 T_{流水} = m△t_0 + (n - 1) △t_0 T流水=m△t0+(n−1)△t0
T 流 水 = m △ t 0 + ( n − 1 ) △ t 0 T_{流水} = m△t_0 + (n - 1) △t_0 T流水=m△t0+(n−1)△t0
S = m / ( 1 + ( m − 1 ) / n ) S = m / (1 + (m - 1) / n) S=m/(1+(m−1)/n)
(3)效率
定义:流水线的利用率,涉及两个时间:通过时间和排空时间。
通过时间:第一条指令通过流水线的时间
排空时间:最后一条指令通过流水线的时间
整个流水线的效率:
E
=
n
△
t
0
/
T
流
水
E = n△t_0 / T_{流水}
E=n△t0/T流水
当n远大于m时,E趋近于零。
5. 限制流水线性能的几个相关
数据相关:需要数据的定向,编译器的调配
结构相关:需要增加更多的硬件资源,如寄存器资源
控制相关:分支操作,判断,转向