计算机组成原理学习笔记(2)

二进制编码

程序 = 算法 + 数据结构
算法-各种计算机指令,数据结构-二进制数据

字符串表示
ASCII码:8位二进制
Unicode

定点数:没办法同时表示很大的数字和很小的数字
浮点数(Floating Point)
在这里插入图片描述

数字电路
门电路:创建 CPU 和内存的基本逻辑单元
在这里插入图片描述

半加器(Half Adder): 异或门计算个位,与门计算是否进位
解决个位的加法问题
在这里插入图片描述

两个半加器和一个或门,组合成一个全加器
在这里插入图片描述

8 位加法器
在这里插入图片描述

乘法:加法+位移
在这里插入图片描述

并行加速方法:把 O(N) 的时间复杂度,降低到 O(logN),N为乘法位数
在这里插入图片描述

门延迟(Gate Delay):以全加器为例,每一个全加器都要等待上一个全加器把对应的输入结果算出来,才能算下一位输出,位数越多,等待时间越长

超前进位加法器:通过复杂电路解决延迟问题
在这里插入图片描述

处理器设计
建立数据通路:指令+运算=CPU
指令周期(Instruction Cycle)
1.Fetch取指令:从 PC 寄存器里找到对应的指令地址,根据指令地址从内存里把具体的指令加载到指令寄存器中,然后PC寄存器自增
2.Decode 指令译码
3.Execute 执行指令
4.重复1~3
在这里插入图片描述

控制器(Control Unit)通过 PC 寄存器和指令寄存器取出指令
算术逻辑单元(ALU)执行指令,简单的无条件地址跳转可以直接在控制器里面完成
在这里插入图片描述

Instruction Cycle
Machine Cycle,机器周期或者 CPU 周期:从内存里面读取一条指令的最短时间
Clock Cycle,时钟周期,机器的主频
在这里插入图片描述

数据通路-处理器单元
组合逻辑元件(Combinational Element):在特定输入下产生特定输出
存储元件:状态元件(State Element)
通过数据总线连接,完成数据的存储、处理和传输

CPU 所需要的硬件电路
1.ALU
2.能够进行状态读写的电路元件-寄存器,存储计算结果,
D触发器(Data/Delay Flip-flop)
3.自动的电路,按照固定的周期,不停地实现 PC 寄存器自增,自动地去执
行“Fetch - Decode - Execute“的步骤
4.译码电路

时序逻辑电路(Sequential Logic Circuit)
1.自动运行问题
2.存储问题
3.各个功能按照时序协调问题

时钟信号硬件实现
CPU主频-晶体振荡器
反馈电路(Feedback Circuit) 反相器(Inverter)

通过 D 触发器实现存储功能
在这里插入图片描述

PC寄存器:时钟信号+D触发器+加法器
每过一个时钟周期,固定自增1
在这里插入图片描述

译码器:读写数据
在这里插入图片描述
在这里插入图片描述

1.自动计数器会随着时钟主频不断地自增,来作为 PC寄存器
2.自动计数器后连上一个译码器,译码器连着大量的 D 触发器组成的内存
3.自动计数器随时钟主频不断自增,从译码器当中,找到对应的计数器所表示的内存地址,读取出里面的 CPU 指令
4.读取出的 CPU 指令写入指令寄存器中
5.指令寄存器后跟一译码器,把拿到的指令解析成 opcode 和对应的操作数
6.输出线路连接 ALU,开始进行各种算术和逻辑运算,对应的计算结果,会再写回到 D 触发器组成的寄存器或者内存当中

面向流水线的指令设计
一整条指令的执行,在一个时钟周期内完成,CPI = 1,单指令周期处理器(Single Cycle Processor)

随着门电路层数的增加,由于门延迟的存在,位数多、计算复杂的指令需要的执行时间就越长-时钟周期和执行时间最长的那个指令设成一样的
在这里插入图片描述

时钟频率没法太高,太高的话,有些复杂指令没有办法在一个时钟周期内完成

指令流水线(Instruction Pipeline)技术
不用把时钟周期设置成整条指令执行的时间,而是拆分成完成一个一个小步骤需要的时间。

把一个指令拆分成“取指令- 指令译码 - 执行指令”三部分,三级的流水线,把“执行指令”拆分成“ALU 计算(指令执行) - 内存访问 - 数据写回”,五级流水线
提升CPU吞吐率
在这里插入图片描述
在这里插入图片描述

每一级流水线对应的输出,都要放到流水线寄存器(Pipeline Register)里面,每增加一级的流水线,就要多一级写入到流水线寄存器的操作
在这里插入图片描述

单纯增加流水线级数,不仅不能增加性能,反而会有更多的 overhead 的开销

冒险(Hazard)
IPC(Instruction Per Cycle)衡量 CPU 执行指令的效率

结构冒险(Structural Hazard):访问内存数据和取指令可能会用到同样的硬件电路,硬件层面的资源竞争

哈佛架构(Harvard Architecture):内存分成两部分,存放指令的程序内存和存放数据的数据内存,各有各的地址译码器
在这里插入图片描述
在这里插入图片描述

把高速缓存分成指令缓存(Instruction Cache)和数据缓存(Data Cache)

数据冒险(Data Hazard):指令 2依赖指令 1 的计算结果,不能在指令1的第一个stage执行完成后进行
乱序执行,把没有依赖关系的指令放到前面来执行

数据依赖:
先写后读(Read After Write,RAW)

int main() {
	0: 55 push rbp
	1: 48 89 e5 mov rbp,rsp

	int a = 1;
	4: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1
	int b = 2;
	b: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2
	a = a + 2;
	12: 83 45 fc 02 add DWORD PTR [rbp-0x4],0x2
	b = a + 3;
	16: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
	19: 83 c0 03 add eax,0x3
	1c: 89 45 f8 mov DWORD PTR [rbp-0x8],eax
}
	1f: 5d pop rbp
	20: c3 ret

内存地址为12的机器码把 0x2 添加到 rbp-0x4 对应的内存地址里,内存地址为 16 的机器码要从 rbp-0x4 内存地址里把数据写入到 eax 寄存器里,需要保证在内存地址为 16 的指令读取 rbp-0x4 里面的值之前,内存地址 12 的指令写入到 rbp-0x4 的操作必须完成

先读后写(Write After Read,WAR)

int main() {
	0: 55 push rbp
	1: 48 89 e5 mov rbp,rsp
	int a = 1;
	4: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1
	int b = 2;
	b: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2

	a = b + a;
	12: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
	15: 01 45 fc add DWORD PTR [rbp-0x4],eax
	b = a + b;
	18: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
	1b: 01 45 f8 add DWORD PTR [rbp-0x8],eax
}
	1e: 5d pop rbp
	1f: c3 ret

在内存地址为 15 的汇编指令里要把 eax寄存器里面的值读出来,再加到 rbp-0x4 的内存地址里,在内存地址为 18 的汇编指令里,要再写入更新 eax 寄存器里面。

写后再写(Write After Write,WAW)

int main() {
	0: 55 push rbp
	1: 48 89 e5 mov rbp,rsp
	int a = 1;
	4: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1
	a = 2;
	b: c7 45 fc 02 00 00 00 mov DWORD PTR [rbp-0x4],0x2
}

流水线停顿(Pipeline Stall)流水线冒泡(Pipeline Bubbling)
在进行指令译码的时候,会拿到对应指令所需要访问的寄存器和内存地址,能够判断出这个指令是否会触发数据冒险。如果会触发数据冒险,可以决定让整个流水线停顿一个或者多个周期
在这里插入图片描述

插入 NOP 这样的无效指令,等待之前的指令完成

NOP 操作和指令对齐
取指令(IF)- 指令译码(ID)- 指令执行(EX)- 内存访问(MEM)- 数据写回(WB),有些指令没有对应的流水线阶段,运行一次 NOP 操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

操作数前推(Operand Forwarding)操作数旁路(Operand Bypassing):通过在硬件层面制造一条旁路,让一条指令的计算结果,可以直接传输给下一条指令,而不再需要“指令 1 写回寄存器,指令 2 再读取寄存器“多此一举的操作
在这里插入图片描述

乱序执行(Out-of-Order Execution,OoOE):后面的指令不依赖前面的指令,就不用等待前面的指令执行,完全可以先执行
在这里插入图片描述

1.在取指令和指令译码的时候, CPU一级一级顺序地进行取指令和指令译码的工作
2.在指令译码完成之后,CPU进行一次指令分发,把指令发到一个叫作保留站(Reservation Stations)的地方。
3.指令等待它们所依赖的数据,传递给它们之后才会执行
4.指令就可以交到功能单元(Function Unit,FU),其实就是ALU,去执行
5.结果存放到重排序缓冲区(Re-Order Buffer,ROB)
6.CPU按照取指令的顺序,对指令计算结果重新排序
7.实际的指令的计算结果数据先写入存储缓冲区(Store Buffer),最终才会写入到高速缓存和内存里

遇到if…else条件分支或for/while循环,顺序执行假设就会不成立

控制冒险(Control Hazard):为了确保能取到正确的指令,而不得不进行等待延迟

条件跳转指令
1.条件比较
2.实际的跳转:指令译码(ID)的阶段进行
缩短分支延迟:在 CPU 里面设计对应的旁路,在指令译码阶段,就提供对应的判断比较的电路

分支预测(Branch Prediction):条件跳转后执行的指令,应该是哪一条
条件跳转一定不发生
预测正确:节省下来本来需要停顿下来等待的时间
预测失败:把后面已经取出指令已经执行的部分给丢弃掉,Zap 或Flush
CPU 需要提供对应的丢弃指令的功能,通过控制信号清除掉已经在流水线中执行的指令
在这里插入图片描述

动态分支预测
用前一天的是不是下雨,直接来预测后一天会不会下雨,叫一级分支预测(One Level Branch Prediction),或者叫 1 比特饱和计数(1-bit saturating counter)
在这里插入图片描述

状态机(State Machine):4 个状态,需要 2 个比特来记录对应的状态,2 比特饱和计数,双模态预测器(Bimodal Predictor)
在这里插入图片描述
在这里插入图片描述

多发射(Mulitple Issue)和超标量(Superscalar):一次性从内存里面取出多条指令,分发给多个并行的指令译码器,进行译码,然后对应交给不同的功能单元去处理。在一个时钟周期里,能够完成的指令不只一条,IPC 也就能做到大于 1 了

在这里插入图片描述

多发射(Mulitple Issue):同一个时间,可能会同时把多条指令发射(Issue)到不同的译码器或者后续处理的流水线中去

超标量(Superscalar):本来在一个时钟周期里面,只能执行一个标量(Scalar)的运算,在多发射的情况下,能够超越这个限制,同时进行多次计算,超标量的 CPU 里面,有很多条并行的流水线
在这里插入图片描述

不同的功能单元的流水线长度不一样, 14 级流水线,指的通常是进行整数计算指令的流水线长度

超标量 CPU 的多发射功能,动态多发射处理器

超长指令字设计(Very Long Instruction Word,VLIW):让编译器来优化指令数,通过编译器,来优化 CPI

显式并发指令运算(Explicitly Parallel Instruction Computer)EPIC

在乱序执行和超标量的 CPU 架构里,指令的前后依赖关系,是由 CPU 内部的硬件电路来检测的,超长指令字的架构里面,这个工作交给了编译器
在这里插入图片描述

让编译器把没有依赖关系的代码位置进行交换,再把多条连续的指令打包成一个指令包

指令级并行(Instruction-level parallelism, IPL):过同一时间执行两条指令,来提升 CPU 的吞吐率

超线程(Hyper-Threading) 同时多线程(Simultaneous Multi-Threading,SMT)
在同一时间点上,一个物理的 CPU 核心只会运行一个线程的指令
在这里插入图片描述

超线程的 CPU,是把一个物理层面 CPU 核心,“伪装”成两个逻辑层面的CPU 核心。这个 CPU,会在硬件层面增加很多电路,使得我们可以在一个 CPU 核心内部,维护两个不同线程的指令的状态信息

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值