计算机组成与设计-处理器
计算机组成与设计-处理器
处理器介绍
CPU性能衡量参数
- 主频:主频 = 时钟频率,它是指CPU内部晶振的频率,常用单位为MHz,它反映了CPU的基本工作节拍;
- 时钟周期: 时钟周期 t =1/ f; 主频的倒数
- 机器周期:机器周期 = m*t ;一个机器周期包含若干个时钟周期
- 指令周期: 指令周期 = mtn; 执行一条指令所需要的时间,一般包含若干个机器周期
- CPI:CPI = m*n; 平均每条指令的平均时钟周期个数
-
MIPS(MillionInstructions Per Second):MIPS = 每秒执行百万条指令数 = 1/(CPI×时钟周期)= 主频/CPI
表示秒钟所能执行的指令条数,对于微型计算机可用CPU的主频和每条指令的执行所需的时钟周期来衡量
一个基本的MIPS实现
-
一个MIPS包含5个处理步骤:
1.从指令存储器中读取指令(IF)
2.指令译码(ID)
3.执行操作或计算地址(EXE)
4.从数据存储器中访问操作数(MEM)
5.将结果写回到寄存器(WB) -
存储器访问指令:load word(lw) 和 store word(sw)
-
算数逻辑指令:add, sub, AND, OR and slt
-
分支指令:brach equal(beq) 和 jump(j)
-
MIPS 指令集:MIPS指令集是RISC精简指令集,拥有RISC的特点,首先其中的所有的指令位数都是32位的,在这32位中有6为用于编码操作种类,所以我们很容易就了解到,它最多有2的6次方条指令(0 ~ 63)共64条。之后的26位根据划分的不同分为I类,R类和J类。其中所有的寄存器引索都是以5为来编码(0 ~ 31其中0号比较特别,它始终是数字0)。
-
I 类 :IF - ID - EXE - MEM -WB
-
R类:IF - ID - EXE - WB
流水线
- 概念:流水线(pipelining)是一种实现多条指令重叠执行的技术。采用流水线技术可以节省大量的时间。流水线是现代RISC核心的一个重要设计,它极大地提高了性能。
对于一条指令的执行过程,通常分为:取指令、指令译码、取操作数、运算、写结果。前面三步由控制器完成,后面两步由运算器完成。按照传统的做法,当控制器工作的时候运算器在休息,在运算器工作的时候控制器在休息。流水线的做法就是当控制器完成第一条指令的操作后,直接开始开始第二条指令的操作,同时运算器开始第一条指令的操作。这样就形成了流水线系统,这是一条2级流水线。
流水线就是利用了空余的CPU资源,使每个部件在每个时钟周期都工作,同一个时钟周期内有多条指令被**,但是这些指令处于不同的状态,有的在取指、有的在译码、有的在执行,但从整体看来就有一条甚至是多条指令被完成,这样大大提高了效率。不过流水线有两个非常大的问题:相关和转移。
面向流水线的指令集设计
MIPS的指令集是为了流水线设计的。
- 所有的MIPS指令长度都是相同的
- MIPS只有很少的几种指令格式
- MIPS中的存储器操作数仅出现在存取指令中
流水线冒险(Hazzard)
流水线有这样一种情况,在下一个时钟周期中下一条指令不能执行,这种情况称为流水线冒险。
有以下三种冒险:结构冒险,数据冒险和控制冒险。
结构冒险
英文:Structual hazzard
-
产生原因:
因缺乏硬件支持而导致计划的指令不能在预期的时钟周期内执行的情况。 -
解决办法1:将存储器分开为数据存储器(DM)和指令存储器(IM);
-
解决办法2:阻塞流水线(Stall the pipeline)当检测到冲突的时候,结果导致了流水线气泡(Bubble)
数据冒险
英文:Data hazzare,也称为流水线数据冒险。
-
产生原因:因为无法提供指令所需的数据而导致指令不能在预期的时钟周期内执行的情况。一条指令必须等待另一条指令的完成,造成了流水线的暂停。
-
在计算机流水线中,数据冒险是由于一条指令依赖于更早的一条还在流水线中的指令造成。举例来说,假设有一条加法指令,它之后紧跟着一条减法失灵,而减法指令要使用加法指令的和。
add r1 , r2 , r3
sub r4 , r1 , r5
在不作任何干涉的情况下,这一数据冒险会严重阻碍流水线。因为减法指令要到第五步才能写回它的结果。这就意味着在流水线中浪费了三个时钟周期。 -
解决办法1:转发/旁路 (forwarding / bypathing)
一种解决数据冒险的方法,目的是想解决数据冒险之前不需要等待指令的执行结束。具体做法是从内部寄存器而非操作员可见的寄存器或存储器中提前去除数据。
- 转发的图示表示:图中的连接表示从add指令的EX操作输出到sub指令的EX操作输入的转发途径,从而替换掉在sub的第二步从寄存器s0读取的值。
只有当目标步骤在时间上晚于源步骤时转发的路径才有效。
图示1:
图示2: - 转发的图示表示:图中的连接表示从add指令的EX操作输出到sub指令的EX操作输入的转发途径,从而替换掉在sub的第二步从寄存器s0读取的值。
-
解决办法2:阻塞流水线(Bubble)
转发可以解决的很好,但不是能避免所有流水线阻塞的发生。例如,假设第一条指令不是add而是装载s0 寄存器的内容,由于时间的依赖,所需要的数据只有在前一条指令流水线的第四级完成之后才能生效,这对sub指令的第三级输入太迟了。
所以,当转发失败时,在遇到装载-使用型数据冒险(load-use Data Hazzard)时,流水线不得不阻碍一个步骤,即流水线阻塞来避免载-使用型数据冒险。
装载-使用型数据冒险:一类特殊的数据冒险,指当装载指令要取的数还没取回来时,其他指令就要执行的情况。
控制冒险
英文:Control hazzard,也称为分支冒险(branch hazzard)。
- 产生原因:因为取到的指令并不是所需要的(或者说指令地址的变化并不是流水线预期的)而导致指令不能在预期的时钟周期内执行的情况。
-
解决办法1:阻塞(Stall)
在第一批衣烘干之前按照之按串行的方式操作,并且重复这一过程直到找到正确的洗衣设置为止。
在每一个条件分支上阻塞是避免流水线控制冒险的一种解决办法。
-
解决办法2:分支预测(Brach prediction):一种解决分支冒险的方法。它预测分支结果并立即沿预测方向执行,而不是等真正的分支结果确定后才开始执行。有动态预测和静态预测。
- 情况1 :分支未发生(Branch not taken),执行flush操作,即从流水线上忽略这条命令,而前面的stall是在流水线上延迟一个时钟周期.
- 情况2 : 分支发生,采用stall来解决。
- 解决办法3:延迟分支:在延迟槽(delay slot)上放一个不影响分支的命令,防止流水线发生阻塞。