跳至主要內容

计算机组成原理

PPLong大约 47 分钟

计算机组成原理

运算方法与运算器

基本运算

位运算

& | ~ ^:可直接采用逻辑门实现,运算延迟为一级门电路延迟

逻辑运算

&& || ! : 非数值运算,操作数只能是0或者1 --> 逻辑运算翻译成汇编语言时不会对应具体的运算指令,而是变成相应的程序分支结构(cmp \ je)

移位运算

<< >> : 2x 4x x/16等都会转换成相应的移位运算 而非乘除法运算

  • 对固定位数的移位运算,不需要逻辑器件,只需要对原有数据进行重排即可
  • 对可变参数的移位运算,可将可变移位运算按权值分解成k(位移数)个固定个数的移位运算 ----> 桶型移位器
    • 纯组合逻辑电路,用k个二路选择器串联构成。k个二进制位分别连接到k个二路选择器的选择控制端
    • 需要k个二路选择器的时间延迟,一个二路选择器需要2级基本门电路延迟

移位操作的原理

算术运算

+-*/:

C语言中的变量 x 常量以及变量 / 常量通常会被编译器优化,常量乘法会被更快的移位指令和算数加减运算指令替代。除法被常量乘法和移位指令的组合替代

定点加减法运算

参考CSAPP,华科书中也有习题

溢出检测

逻辑实现

全加器

3个输入: 要加的两个位数 X Y、是否有来自低位的进位 C_{i}
2个输出: 是否有高位的进位C_{i}、相加的结果S_

Si=XiYiCi S_{i}= X_{i} \bigoplus Y_{i} \bigoplus C_{i}

高位进位输出的两种表达方式:

Ci=XiYi+(Xi+Yi)Ci C_{i}= X_{i}Y_{i} + (X_{i} + Y_{i})C_{i}

Ci=XiYi+(XiYi)Ci C_{i}= X_{i}Y_{i} + (X_{i} \bigoplus Y_{i})C_{i}

开销不同:

  • ①式:3个两输入与门、1个三输入或门、2个两输入异或门
  • ②式:2个两输入与门、1个两输入或门、2个两输入异或门,成本低,延迟高

注意这里主要是$$C_{i+1}$$的运算区别

半加器

没有进位输入、内部逻辑只有一个异或门来产生合数,一个与门产生进位输出

S_i = X_i \bigoplus Y_i$$ $$C_{i+1} = X_iY_i

半加器通常用于没有进位输入的情况,以减少不必要的硬件开销,时间延迟为3T

多行串行加法器

n个全加器的进位链串联得到n位串行加法器 ----> 行波进位加法器

高位的全加器必须等待低位进位后才能开始运算。但S和C的运算是并行的互不等待的有符号、无符号运算均可

  • 无符号的加法:溢出检测信号 $$C_n$$
  • 有符号 溢出检测:overflow,最高数值位进位和符号位进位异或得到
可控加减法电路

[X][Y]=[XY]=[X]+[Y] [X]_补 - [Y]_补 = [X-Y]_补 = [X]_补 + [-Y]_补

Y的所有位与Sub信号进行异或后送入 Sub = 1时,则送入的是Y的反码,并且Sub也实现了末尾+1的取反操作

先行进位加法器(CLA)

n位串行加法电路高位的运算以来与低位进位输入,全加器并不能并行运行,位宽较大时性能差

替换: $$G_i = X_iY_i$$ $$P_i= X_i \bigoplus Y_i$$
Gi = 1时,Ci+1一定为1 ---- Gi:进位生成函数
Pi = 1,Ci才能传递到进位输出Ci+1---Pi:进位传递函数
最终有:

Gn=Gn1+Pn1Gn2+...+Pn1Pn2...P2P1P0C0 G_n = G_{n-1} + P_{n-1}G_{n-2} + ... + P_{n-1}P_{n-2}...P_2P_1P_0C_0

根据公式利用欧冠额外的组合逻辑电路提前产生各位运算加法所需要的所有进位输入,再利用$$S_i = P_i \bigoplus C_i$$进行一级异或门运算可得到最终的和数,n越大,时间延迟也大,通常按照4位一组进行先行进位(先行进位电路位数越多、扇入系数越大、制造难度越大)

并行加法器

4位先行进位电路 + 生成GP的与门异或门电路 + 4个异或门 = 4位快速加法器(并行加法器)

如何构建更大位宽的加法器电路?

多个快速加法器的进位链串联(但组间仍然是串行计算)。可以考虑将4个4位快速加法器输出的成组进位生成、传递函数和C0连接到先行进位电路的输入端,产生4个进位信号,再对对应信号连接到相应的快速加法器的进位输入端即可构成16位组内并行进位、组间并行进位的快速加法器

补码加减法

主要理解从原码到补码的优化过程

一种补码诞生的思路,设 a(known) + b(unknown) = 0,根据进位规则来求b,最终诞生了补码

image-20220405102442407
image-20220405102442407

补码加减法的好处

能够让计算机通过加法也能运算出有正负数和进位时的正确结果,方便计算。而不用通过原码运算后再复杂的判断大小。并且也可以只用加法器实现加减法

知识:

  • ~a = -a -1;
  • 当我通过加法计算出一个负数的补码时,我如何确定它的原码的表示数值。按照补码的规则倒推,先减1再取反

所有就有对signed int = (1 >> 31) - 1,其数值等于 -(1>>31),其实理解应该从位的方式先理解,然后再转化到具体的表示形式有不同的取值,如果是unsigned int则为原值

定点乘法运算

  • 多位加法器循环累加,硬件开销小但需要时序电路控制,需要多个时钟周期才能得到运算结果
  • 加法器阵列构成的纯组合逻辑电路,硬件开销大但只需要一个时钟周期

原码乘法

基本累加核心公式: $$P_{i+1} = (P_i + y_{n-1}|x|)2^{-1}$$

两个n位数参加乘法运算需要 n次加法和n次移位操作,需要长度2n的积寄存器,符号位单独参加运算

  • 需要多输入全加器 ---> 基于FA的循环累加0或被乘数
  • 不同位部分左移次数不同 ---> 右移部分积 乘数寄存器
  • 需要长度为2n的积寄存器 ---> 从部分积和乘数寄存器取结果

**同步逻辑右移:**P y拼接在一起进行逻辑右移

核心是理解为什么会将y和P放在一起,进行同步逻辑右移:公式+便捷

补码乘法

[xy]=[x](0.Y1Y2Y3..Yn)Y0[X] [x*y]_补 = [x]_补 * (0.Y_1Y_2Y_3..Y_n) - Y_0 * [X]_补

展开后可得: $$[X * Y]补 = [X]补 * \sum^n (y - y_{i})2^{-i}$$

  • i=n时,y_n+1 = 0
  • yn+1是哪个寄存器? 在乘数寄存器Y后增加一位,为了乘法按照规则进行
  • 算数右移的对象有哪些? 部分积和乘数寄存器

符号位参加运算

  1. Booth算法

  2. 补码一位乘法算法

    逻辑左移、逻辑右移

乘法运算器设计

原码一位乘法

image-20211025135856404
image-20211025135856404

补码一位乘法

image-20211025142032069
image-20211025142032069
  • 需要时序控制(A-> ALU...)
  • 需要多次循环累加

阵列乘法器

与门阵列+FA阵列

原码阵列乘法器

原理:

image-20211025141255448
image-20211025141255448

具体实现: (手工乘法)

image-20211025140622036
image-20211025140622036

每一行都是串行进位加法器 ,改进后(打破串行进位链)

image-20211025140828023
image-20211025140828023

速度更快,同级的FA不存在串行进位了,但需要 增加一行,处理最后一行FA的进位关系

补码阵列乘法器设计

image-20211025142135047
image-20211025142135047

算前求补和算后求补

定点数除法

手工除法怎么算 ----> 启示:除法运算可通过减法实现

存在问题:

  • 除数右移次数可能很多
  • 需要长度为2n的寄存器保存余数
  • 如何判断每步是否够减
    • 余数为正时,商1,将余数左移1位,再与除数做比较
    • 余数为负,不够减,商0。加除数来恢复成原来的值,将余数左移一位并做比较
image-20211025143233972
image-20211025143233972

注意:最终算出来的余数是经过左移改变的,所以需要进行相应位数右移来还原

缺点:运算步数不能在运算之前就确定(来源:恢复余数的次数无法确定)

加减交替法(不恢复余数法)

余数< 0 时不需要恢复,仍然左移,只是再加上Y,结果是和恢复余数是一样的

过程简单、运算步数固定(???)

电路图

image-20211025143922168
image-20211025143922168

阵列除法

可控制加/减单元 CAS

image-20211025144253229
image-20211025144253229

逻辑功能:

Si=Ai(BiP)Ci S_i = A_i \bigoplus (B_i \bigoplus P) \bigoplus C_i

Ci+1=(Ai+Ci)(BiP)+AiCi C_{i+1} = (A_i + C_i) (B_i \bigoplus P) + A_i C_i

P=0时实现加法功能,P=1时实现减法功能

image-20211025144819745
image-20211025144819745
  • 第一步一定是减法 P=1,后面则取决于每一步的商
  • 最左边的CAS的进位输出是商,且本位商决定下一步是加操作还是减操作
  • 每执行完一步除法,除数就右移一位(手工除法)(CAS电路都向右偏移一列,间接实现了余数的左移)

浮点运算

规格化浮点数,将数据的表示范围和精确度统一

规格化的浮点数补码形式 尾数形式为:
00.1xxxx、11.0xxxxx(最高有效数据位与符号位不能相同)

  • 结果为00.0xxxxx或者11.1xxxx,需要左规格化,将尾数向左移动,每移动一次,阶码-1,知道满足要求
  • 尾数结果为01.xxxx或者10.xxxxx,表明尾数求和结果>1,仅需执行一次右移,阶码+1即可

x = 2^{Ex}* Mx$$ $$ y = 2^{Ey} * My

x+y=(2ExEyMx+My)2Ey x + y = (2^{Ex - Ey} * Mx + My )* 2^{Ey}

步骤:

  1. 对阶
    1. 求阶差Ex + (- Ey)
    2. 右移阶码小的浮点数的尾数并同步增加其阶码,直到两数阶码相等
  2. 尾数加减
  3. 结果规格化
  4. 舍入:右移规格话的同时可能丢失一些低位的数值位,为提高精度,可采用
    1. 0舍1入:若右移出的最高位是1,则在最低位加1
    2. 恒置1:只要数字位1被移走,就将最后1位恒置1
  5. 溢出处理:
    1. 阶码上溢:阶码的符号位为01
    2. 阶码下溢:阶码的符号位为10

浮点乘法和除法都大同小异

存储器系统

存储器概述

**存储单元:**存储器中的最小存储单位 -- 存储元

**MOS:**场效应管。金属+氧化物+半导体场效应晶体管

分类

按照存储介质分类

  • 磁存储器:磁性材料做介质,利用磁化单元剩磁的不同磁化方向来存储数据0 和 1.体积大、存储速度慢、单位容量成本低

  • 半导体存储器:

    • 双极型存储器: TTL、ECL

    • 金属氧化物半导体存储器:MOS存储器

      • 静态MOS存储器 SRAM
      • 动态MOS存储器 DRAM

      存储体积小,存储速度快,单位容量成本高

  • 光存储器: 利用介质的光学特性(CD-ROM DVD-ROM)以刻痕形式将数据存在盘面,用激光束照射盘面,靠不同的反射率来读信息

    • 磁光盘:激光+热辅助磁化的方式,根据反射光的偏振方向不同读信息

按照存取方式分类

  • 随机存储器:RAM,按照地址随机读写数据存储单元,存取访问时间与存储单元的位置无关。现在大量的半导体存储器都是RAM
  • 顺序存储器:SAM,存储单元的内容只能依地址顺序访问,访问速度与存储单元的位置有关的存储器(磁带存储)
  • 直接存储器: DAM,不必经过顺序搜索就能在存储器中直接存取信息,具有RAM和SAM的特性(磁盘存储器)。由于磁盘存在机械寻道和旋转延迟,因此数据访问时间和磁头与目标扇区的距离有关

按照信息的可改写性

  • 读写存储器:既能读出又能写入信息
  • 只读存储器:ROM

按照功能和存取速度分类

  • 寄存器存储器(CPU类)
  • 高速缓冲存储器: 在寄存器和驻村之间的高速小容量存储器,存放CPU即将或者经常要使用的指令和数据。采用静态RAM构成
  • 主存储器:CPU中除了寄存器之外唯一能直接访问的存储器,存放执行和数据。CPU通过主存地址直接、随机地读写存储器。主存一般由半导体构成,可能还包括硬件端口和BIOS
  • 外存储器: 容量大、速度低。存放当前暂时不参与运行的程序与数据

存储器带宽: 单位时间内存储器能传输的信息量 (位/秒 字节/秒)

存储系统层次结构

主存的基本结构

主存是机器指令直接操作的存储器,采用主存地址进行随机访问

  • 地址译码器接收到来自CPU的n位地址信号,经过译码、驱动后产生2^n根地址译码信号,每一根地址译码信号连接一个存储单元
  • 数据寄存器永远是存取将要送走或者送来的数据
  • 读写控制相当于一个网关,产生读写的信号

主存中的数据存放

存储字长: 主存的一个存储单元所存储的二进制位数
数据字长(字长): 计算机一次能处理的二进制数的位数
存储字长和数据字长可以不同

(网上说数据字长是计算机数据存储所占用的位数,机器字长是CPU一次能处理数据的位数)

地址访问模式

主存按照字节进行编址,可以通过字节地址、半字地址、字地址(字节地址的逻辑右移)来进行访问

大端小端

不同的访问顺序导致访问的数据完全不同

  • 小端: 存储器的低字节地址单元存放的数据的低字节
    • 主流处理器采用
  • 大端: 存储器的低字节地址单元存放的数据的高字节

数据的边界对齐

一个多字节变量分布在不同的字存储单元中,访问改变量就需要多个存储周期

  • dw数据起始地址的最末3位为000,地址是8的整数倍
  • w数据起始地址最末两位为00.地址是4的整数倍
  • 半字树其实地址的最低一位是0,地址是2的整数倍
  • 单字节数据不存在边界对齐问题

以空间换时间,理解为什么需要内存对齐open in new window

半导体存储器

存取速度快,体积小,性能好 分为RAM和ROM存储器

作为存储单元电路,需要具备:

  • 具有两种稳定状态
  • 状态经外部信号控制可相互转换
  • 经控制后能读出其中的信息
  • 信息能长期保存

6管MOS存储单元

存储单元扩展

静态MOS存储器

一维行扩展: 单译码结构
二维行列扩展: 双译码结构,两个方向设置n/2路输入译码器。输出信号少很多(为啥?),译码电路成本降低

译码器(最小项发生器):组合逻辑电路,将n位二进制信号输入翻译成2^n个输出信号,每个输出信号都是n位输入的最小项

结构

动态MOS存储器

SRAM存储密度低,即使存储单元不写入,也会有电流,功耗大

  1. 单管DMOS存储单

    一个MOS管+ 一个电容

    缺陷:

    1. DRAM利用存储电容的电荷表示数据,重发点过程慢,导致了读写速度比SRAM单元慢
    2. 存储电容的容量比寄生电容小一个容量级,二者进行电荷重分配产生的电流十分微弱,需要灵敏的差分放大器检测。读操作可能导致电荷减少,破坏原有数据,为避免数据丢失,读出后会将数据重新写入---数据恢复
    3. 数据恢复以及读出信号放大的逻辑由再生放大电路实现,每组列线上共享
    4. 电容的电荷会逐渐泄露,数据只能保存较短时间。需要类似读操作的方式对存储单元补充电荷---刷新----为什么叫DRAM
  2. 如何刷新

    最大刷新周期: 信息存储到数据丢失之前的时间间隔
    刷新周期:存储器实际完成两次刷新的间隔(2ms 4ms 8ms/...)

    动态存储器按行进行刷新,为减少刷新周期,可减少存储矩阵的行数、增加列数,只需要给出行地址即可

    刷新时DRAM不能响应CPU的访问,三种解决方式

    • 集中刷新
      • 读写操作期间不受刷新操作的影响,存储器速度快
      • 存在较长的时间死区,在集中刷新的n个读写周期内,CPU都不能访问存储器
    • 分散刷新
      • 划分存储周期,前段时间来读写 后端时间来刷新(类似微时隙再分),则过n个ts就可以完全刷新,在一个刷新间隔内能进行多次刷新
      • 不存在死区
      • 刷新过于频繁,影响系统速率
    • 异步刷新
      • 集中刷新+分散刷新
      • x行的刷新平均分散在刷新间隔内,每个一段时间刷新一行,将刷新间隔的最后0.5us来刷新
      • 充分利用2ms时间,保持了系统的告诉特性

只读存储器

  • 掩膜式ROM MROM:把0 1 信息存储在掩膜图形中,芯片完成后各存储位状态被固定,不能修改。灵活性差可靠性高
  • 可编程ROM PROM :用户可写一次,采用熔丝代替开关,存储器出厂时每个存储单元的熔丝都是连接状态,存储数据全为0.可利用编程器进行一次改写,可通过辅助电路有选择地将某些存储单元的熔丝高压熔断,再写入数据1
    • 除熔丝型,还有采用反向二极管的PROM,默认状态不导通,默认数据为1,改写时采用高压将其永久性击穿,导通数据为0.
  • 可擦除可编程ROM EPROM:可多次写入,可擦除进行重写
    • 浮置栅:MOS管的栅极埋入SiO2中且浮空与外界绝缘。
    • 利用浮置栅MOS管的导通和截止状态存储数据,初始无电荷,MOS管截止;写入时在源级和漏级加上编程电压,MOS管在高压作用下被击穿。高压撤出后,浮置栅有绝缘层保卫,电荷无法泄露,浮置栅带电,MOS管导通,信息存入
    • 擦除:紫外线照射,形成光导现象,浮置栅上电荷完全泄露。所有单元回到初始状态
  • 电可擦除可编程ROM EEPROM:在浮置栅上方增加了控制栅极,写入方式与EPROM相同。
    • 擦除时不需要紫外线照射石英玻璃,只需要将控制栅极加上高电平就可以将浮置栅的电荷泄露掉
    • 可以精准地删除某一存储单元
  • 闪存 Flash Memory:快速擦写、非易失性存储器。与EEPROM结构相似。闪存的工作方式包括读工作方式、编程工作方式、擦除工作方式和功耗下降方式,编程和擦除方式采用写命令到命令寄存器的方法来进行。

主存的组织和与CPU的连接

单片存储芯片的容量有限,通常需要将多篇存储芯片按照一定方式组织并与CPU连接。

存储器的扩展

  1. 位扩展

    字长扩展、数据总线扩展

    当存储芯片的数据总线位宽 < CPU数据总线位宽时采用

    将所有存储芯片的地址线、读写控制线并联分别与CPU的地址线和读写控制线连接,存储芯片的数据线和CPU数据线连接;所有芯片的片选控制线并联后与**CPU的访存请求信号MERQ#**连接

  2. 字扩展

    容量扩展、地址总线扩展

    存储芯片的存储容量不能满足存储器对存储容量的要求时采用。

    将所有存储芯片的数据线、读写控制线各自并联,分别与CPU的数据线和读写控制线连接

  3. 字位同时扩展

    存储芯片的数据位宽和存储容量均不能满足存储器的数据位和存储总容量时采用

    先位扩展 -- 后字扩展

并行主存系统

如何通过发觉存储系统的并行性来提高存取速度

  1. 双端口存储器

    一个存储器有两组相互独立的端口,每个端口可以独立地进行读写操作

    特点:

    1. 并行读写

      不同端口使用各自的地址线、数据线和控制线对存储器中的不同存储单元进行同时读写

    2. 冲突处理

      两个端口地址相同时会发生读写冲突 ,解决 ----> 每个端口设置标志 $$\overline {BUSY}$$,由判断逻辑决定哪个端口有限进行读写操作,另一个端口的标志设置为0(低电平)以延迟对存储器的访问。优先端口的操作完成后,被延迟端口的标志会复位

      效率不能实际提高两倍 ----> 冲突访问不能避免

  2. 单体多字存储器

    类似位扩展方式。多个存储模块共享地址总线,按同一地址并行访问不同存储模块的同意单元,一个存储周期内访问多个存储字。

    常用: 多通道内存技术 (联动模式):
    两条完全相同的64位内存共享地址总线和片选信号线, 同一时刻两根内存并发工作,各自访问同一地址单元中的64位数据(总共128位)并送入内存控制器。(要求两根内存的容量、时序、频率必须完全一致(书中有图,非常帮助理解))

    非联动模式:内存控制器通过独立的片选信号、地址总线、读写控制线连接两根内存,数据总线页是独立的两条64位总想爱你。内存可以并发工作,但二者地址、读写命令不必同步。只需要频率相同

  3. 多体交叉存储器

    多个容量和存取速度相同的存储模块构成

    1. 高位多体交叉(顺序编址模式)

      目的:扩充存储器容量,与存储器字扩展完全相同。用高位地址译码产生片选信号,选择不同的存储模块;低位地址直接选择存储模块内的不同存储单元

      特点:

      • 相邻地址在同一存储体内
      • 不同存储体中的地址不相邻
      • 同一存储体的地址单元是连续的,程序执行过程基本是对同意存储提访问频繁,而其他存储提基本空闲,无法实现多个存储体的并行工作

      eg:计算机内存插槽可扩展性

    2. 低位交叉方式(交叉编址模式)

      低位地址译码进行片选,高位地址选择存储模块内的不同存储单元

      特点:

      • 相邻的地址处在不同的存储体内
      • 同一存储体中的字体不相邻
      • 适合突发的顺序访问模式
      • 顺序访问时,各存储模块按照流水线的方式轮流存取

      为提高顺序访问时个存储模块的并行性,个存储模块均具有各自独立的地址寄存器、数据寄存器和读写控制电路。

计算不同条件下读取字所需要的时间和带宽 --- 书中P.121

存储时间和存储周期的区别

存储时间:CPU读写内存内数据的过程时间(发出命令到接受数据)
存储周期:连续启动两次读或写操作锁需间隔的最小时间(两次存储时间+恢复时间)

高速缓冲存储器

cache

SRAM速度快但容量有限,成本高功耗大。 为进一步提升CPU访问主存的性能 --- 在CPU和主存间增加隐藏的小容量快速的SRAM
将主存中经常访问或者即将访问的数据副本调度到小容量的SRAM中,使得大部分数据访问都能在cache中进行(为什么?因为CPU执行的程序具有较强的程序局部性)

程序局部性

程序在执行时呈现局部规律性(一段时间内,程序的执行仅限于程序中的一部分,执行所需的执行和数据页局限于某个存储区域内)

  • 空间局部性:一旦程序访问了某个存储单元,其附近的存储单元页即将被访问(代码、数组、结构体、全局变量)
  • 时间局部性:程序访问一个存储位置,该位置在未来可能被多次访问(循环结构)
概念

与主存一样,被分为多个数据块,数据块又包含多个字。划分为块地址和块内偏移地址(主存块地址字段>cache块地址字段,块内偏移是相同的)

CPU通过字节地址访问cache先判断数据是否在cache中,如果在,则数据命中
数据不在,数据缺失,缺失时的访问时间叫缺失补偿(包括数据查找t、主存访问t、cache访问t),相邻数据也会随着数据块一起加载到cache中

读写流程

CPU需要访问主存时,先以主存地址RA中的主存块地址为关键字在查找表中查找,能查到则命中

以主存字节地址WA中的主存块地址为关键字在查找表中进行数据查找,先写到cache再写到主存
脏数据:cache中数据和主存中原始数据不一致现象

  • 写回策略:不再写入到主存,响应速度最快,但产生不一致性。每个cache行要配置一个修改位(脏位)。当某行要被替换时,检测是否脏位为1,是则会写入到内存中再替换
  • 写穿策略:写回到主存中,慢速

数据缺失时:

  • 写分配法:将WA对应的数据块载入到cache中,在进行和写命中一致的策略。
  • 另外的:数据直接写入慢速的主存中

关键技术

  1. 数据查找
  2. 地址映射
  3. 替换策略
  4. 写入策略

相联存储器CAM

按内容进行访问的存储器,用于存放查找表 KV形式。用于cache的快速查找

所有存储单元的key字段同时与CAM的输入检索关键字进行并发比较。每个存储单元都对应一个独立的比较器,硬件成本高,容量一般较小

地址映射

主存地址空间映射到cache的地址空间,三种方式:

  1. 全相联:各主存块可映射到cache的任意数据块

    (主存)一对多(cache),新的主存块可以在啊入道cache中的任意空位置。
    利用率最高、查找成本高,需要CAM提供快速查找功能

    需要记录相关标记:主存块地址标记、有效位、脏数据标志位.... ---cache槽中(cache有多少个数据块就对应多少个cache槽)

    数据查找时直接将主存块地址和所有cache行中的标记字段主存块地址进行并发比较

    cache副本缓冲区容量 = n x 2^w字节 实际容量为 n * (1+s+8*2^w)位(s :tag, w: offset)

    实现:

    主存地址被划分位(tag,offset),tag代表主存块地址。比较时tag与所有航的标记字段tag进行多路并发比较

    特点:

    1. cache利用率高
    2. cache冲突率低
    3. 查找时要并发比较查找表的所有项,硬件成本高,适合小容量cache
    4. cache满载时替换算法复杂
  2. 直接相联:主存块只能映射到cache中的固定块

    每个主存地址只能映射到cache中的固定行

    cache行号i = 主存块号 j mod (cache行数n)

    主存地址可细分为:区地址tag、区内行索引index、块内偏移offset

    cache实际容量n * (1 + s -r + 8 * 2^w)位(行数位r,区地址有s-r位)

    通过index字段可快速访问对应cache行的标记与标志字段,如果标记字段有效与主存地址中的区地址相同,就命中。查找表不需要存放在相联存储器中

    实现:

    主存地址被划分为 (tag index offset)

    特点:

    1. cache利用率低,可能有冲突
    2. cache未满也可能发生数据冲突
    3. 查找时只需要根据index访问对应cache行的tag比较,一个比较器即可,硬件成本低(因为不需要并发比较了),适合大容量cache使用
    4. 不需要使用复杂的替换算法

    相应例题 : P.130(还挺多的,建议好好看一下)

  3. 组相联:主存快只能映射到cache固定组中的任意块

    前两种方式的折中,既能提高命中率,又能降低硬件的开销(全相联在组内进行比较,需要K个比较器)

    将cache分成固定大小的组,每组k行(k-路组相联)。主存数据块首先先采用直接相联映射的方式定位到固定的组,然后用全相联映射方式映射到组内的任何一个cache行。

    cache组号 = 主存块号 mod(cache组数)

    实现:

    主存地址被划分位(tag 组索引index offset)

    cache容量 = 2 n * (1+s-d+8* 2^w)位

    数据淘汰在指定的组内选择cache行进行淘汰

应用

分离cache

指令和数据不在同一个cache中统一cache:指令和数据都在cache中,,但执行部件存取数据时,指令预取部件又要从统一cache读指令,两者会发生冲突

多级cache

一级cache L1: cache和处理器集成在同一芯片内,减少对片外总线的访问。容量较小
二级cache L2: 主存和CPU之间(L1cache容量小 8 K, L2-- 256KB~1MB)

替换算法

  1. FIFO:

    需要记录每个cache行载入cache的时间戳,开销小

  2. LFU:Last Frequently Used

    每行必须设置淘汰计数器,可能因为时序问题而淘汰使用增长率较高的cache行

  3. LRU:Last Recently Used

    每行设置计数器,每命中一行,对应的计数器清零,其他行的计数器+1.使得cache有较高的命中率

    难点:快速比较多行计数 --- 二路级联cache,一个主存快只能在特定组的两行中存放(二选一)

  4. 随机替换

虚拟存储器

原理

采用cache提高了CPU对主存的访问速度问题,但不能解决主存容量不足的问题
虚拟存储器处于“主存-缓存”层次,通过增加部分软件和硬件,使得赋存和主存构成一个整体,就像一个单一的主存可供CPU直接访问。程序员可用虚拟存储器提供的虚拟地址进行变成,不再受主存大小的限制。

利用程序的局部性,采用按需加载的方式加载代码和数据。加载程序时不直接加载入主存中,而仅在相应的虚拟地址转换表中登记虚拟地址对应的磁盘地址。程序执行病访问虚拟地址对应的程序和数据时,产生缺页异常,将真正的程序和代码载入

地址映射

虚拟存储器中三种空间地址

  1. 虚拟地址空间:编写程序的地址空间
  2. 主存地址空间:物理地址空间(实地址空间)
  3. 辅存地址空间:磁盘存储器地址空间

地址映射:将虚拟地址空间映射到主存空间,将访问的内容按照某种规则从辅存装入主存并在虚、实地址间建立联系
地址转换:程序被装入主存实际运行时,把虚地址转换成实地址或者磁盘地址,让CPU从主存或磁盘中读取信息

在虚存系统中运行程序时,CPU以虚拟地址访问主存,使用MMU(存储管理控制部件)找出虚地址和实地址之间的关系,并判断这个虚地址对应的内容是否在主存中,如果在则通过MMU将虚拟地址转化为物理地址;如果不在,则把包含这个字的一页或一个程序段调入主存

根据虚拟存储器对主存逻辑结构划分的粒度,虚存可分为页式、段式、段页式虚存

页式虚拟存储器

以页位逻辑结构划分你信息传送单位的虚拟存储器。
虚拟空间和主存空间 被划分成固定大小的页(常见4KB)

虚拟地址划分

虚拟地址 = 虚拟页号 VPN + 虚拟页偏移 VPO
物理地址 = 物理页号 PPN + 物理页偏移 PPO
(VPN > PPN 取决于虚拟空间和主存空间的容量, VPO = PPO 决定页面大小)

页表

虚实地址的转换通过页表进行:一张保存虚拟页号VPN和物理页号PPN对应的关系的查找表,由若干个表项组成的数组。
以VPN作为索引,每个表项包括有效位和物理页号,还包括修改位、使用位、权限位等....

磁盘分为交换分区和数据分区,交换分区用于存放主存页面换出的动态修改数据,数据分区用于存储用户程序和数据,主存和磁盘两部分空间合并构成虚拟地址空间

页表常驻内存,并将虚拟地址中的虚拟页号作为索引来访问。每个虚拟页对应一个页表项,

由于每个进程都有独立的虚拟地址空间,因此每个进程都有一张完整的页表(页表属于进程控制信息,存放在进程地址空间的内核区中)。页表在主存的首地址记录在页表基址寄存器PTBR中,进程切换时只需要切换PTBR的值就可以实现页表的快速切换。

VA:虚拟地址
PA:物理地址
PTE:页表项
PTEA:页表项地址

页表项的有效位 = 1 -> 当前页的数据在主存中,直接利用PPN和VPO生成物理地址,访问主存数据
有效位 = 0 -> 对应虚拟页可能暂未分配页;也可能对应页在磁盘中,访问页会触发缺页异常,由操作系统的缺页异常处理程序负责将磁盘的对应页载入到主存中,并更新页表项。(书中有图和例题 P.141)

VPN+PTBR -> 页表主存中位置 -- > PPN PPN + (VPO-->PPO) = PA

虚存的访问流程

书中详解 P.142

结合cache的虚存器访问流程

页表的部分数据块可能会作为常用的热数据调度到cache中

最佳情况:2次cache访问(数据和页表都在cache中命中)
最坏情况:2次主存访问+磁盘访问(页表数据均未命中且缺页)

利用TLB加速续存器地址转换

cache缓存部分常访问的页表块的数据粒度太大,并不能充分利用虚拟存储器访问的局部性。
为了进一步降低虚拟存储器地址转换的硬件开销,处理器都维护一个转换旁路缓冲区(TLB,一个较小的cache),用于缓冲经常访问的PTE。采用全相联和组相联,随机替换算法。

采用组相联cache的地址划分方法,虚页号划分成TLB标记和TLB索引,便于快速判断访问的页面是否在主存中,标记字段是TLBT
VPN = TLBT + TLBI + VPO
采用全相联的映射,则TLB表项中的标记字段就是VPN,

TLB离CPU更近,访问速度更快,将TLB称为快表,根据内容访问,主存的页表叫慢表,根据地址访问。

进行地址转换时,会同时查询块表和慢表

CPU访存过程

操作系统引导完成之前 --- CPU只能以地址访问主存
引导完成后--进入保护模式,只能用虚地址访问主存

书中P.145有具体图

书后习题非常重要,注意这章的概念解释

指令系统

概述

指令:用户使用计算机与计算机本身运行的基本功能单位
机器指令:计算机硬件与软件的界面,用户操作和使用计算机硬件的接口

一条高级语言 ---> 多条机器指令
一条汇编语言 --->(一般)一条机器指令
一条机器指令 ---> 多条微指令

指令系统应该满足的条件:

  • 完备性
  • 规整性:对称性+均齐性。寄存器和存储单元可以被同等对待,所有志林可以使用各种寻址方式;指令系统提供不同数据类型的支持
  • 有效性
  • 兼容性
  • 可扩展性:指令格式的操作码预留一定的编码空间 ,方便扩展指令

指令格式

指令字长:一条指令中的二进制位数

  • 定长指令系统:
    • 结构简单,方便硬件实现,有利于CPU取指令、译码和指令顺序寻址
    • 平均长度偏长,冗余状态多,不方便扩展
  • 变长指令系统:
    • 结构灵活、长度可变,冗余状态少,可扩展性好
    • 取指令可能涉及多次访存操作,下一条指令的地址必须在指令译码完成后才能确定,增加硬件设计难度(Intel x86)

指令可分为:半字长(CPU访问1次可读取2条)、单字长(CPU1次访问1条)、多字长。
长度越大,占用主存空间大,访问时间长

指令地址码

指令可分为:

  1. 三地址指令

    **双目运算:**具有两个操作对象的运算。两个源操作数+一个目的操作数

    A3(A1)OP(A2) A_3 \leftarrow (A_1)OP(A_2)

    3地址码很少用存储单元的地址码,一般3个操作数都是寄存器

  2. 双地址指令

    A1(A1)OP(A2) A_1 \leftarrow (A_1)OP(A_2)

    可分为:

    • RR(寄存器-寄存器)型
    • RS(寄存器-存储器)型
    • SS(存储器-存储器)型
  3. 单地址指令

    1. 单目运算类指令

      A1OP(A1) A_1 \leftarrow OP(A_1)

    2. 隐含操作数是双目运算类指令

      A1(AC)OP(A1) A_1 \leftarrow (AC)OP(A_1)

      一个操作数隐含于CPU的某个寄存器

  4. 零地址指令

    只有操作码字段没有地址字段。类似单地址指令,也有两种方式

    1. wait ret halt nop不需要任何操作数
    2. 隐含操作数指令

指令操作码

  1. 定长操作码,定长优点同上。

  2. 变长操作码,优点同上。

    可采用扩展操作码技术来实现变长曹组好吗,操作码的长度随地址码数目减少而增加。书中有图题P.157

寻址方式

指令存放在主存中

指令数寻址方式

  1. 顺序寻址

    指令在主存中 往往按序排放

  2. 跳跃寻址

    程序出现分支或转移时,要改变执行顺序。即下一条的指令不一定能通过PC+1来取到

    例如:无条件跳转指令和条件跳转至零

操作数寻址方式

操作数来源:

  1. 直接来自指令地址字段?
  2. 存放在寄存器中
  3. 存放在存储器中

将地址码字段细分为寻址方式字段I 和地址字段D , 例如单地址指令可划分为

image-20211027093000063
image-20211027093000063
  1. 立即寻址

    I表示立即寻址的编码,D字段是操作数本身。操作数和指令同进退,取指令时操作数随着指令一起被送到CPU的指令寄存器中,执行指令时直接从执行寄存器获取操作数

    取操作数快,但形式地址字段D位宽有限,操作数能表示的范围有限,一般用于变量赋初值

    MOV EAX, 2008H

  2. 直接寻址

    操作数在主存中,操作数地址由D直接给出

    直观,不需要计算就可直接从指令中获得操作数有效地址

    但寻址范围受限于指令中直接地址的二进制位数,数据地址存在指令中、程序和数据在内存中的存放位置受到限制

    MOV EAX , [2008H]

  3. 寄存器寻址

    D表示寄存器的编号

    MOV EAX,ECX

  4. 间接寻址

    D给出的是操作数的间接地址。地址指向的主存单元中的内容才是操作数的有效地址

    MOV EAX , @2008H;

    • 解决了直接寻址方式寻址范围受限的问题,能用较短的地址码访问较大的主存空间
    • 灵活,操作数地址改变不需要改变指令中的形式地址,只需要改变其指向的主存单元内容即可

    但取操作数时需要两次访问主存,降低了指令的执行速度

  5. 寄存器间接寻址

    操作数地址存放在寄存器中,实际操作数在主存中(寄存器指向主存的地址)
    只需要一次访问主存,还可以扩充寻址范围
    MOV AL,[EBX]

  6. 相对寻址

    把PC的内容(下一条指令地址)加上指令的形式地址D,形成操作数的有效地址

    数据有效地址 EA = PC + D ,取指令时PC的值会修改,而计算操作数的有效地址在指令译码分析或执行阶段完成,所以有EA = PC + 1 + D???

    • 只需要确定程序内部操作数与指令之间的相对距离,无需知道操作数在主存的绝对地址
    • 分支转移类指令,实现相对跳转转移,有利于程序在主存中灵活定位
  7. 变址寻址

    指定一个寄存器用来存放变化的地址 ,叫变址寄存器。形式字段D增加变址寄存器字段X 。X +D 就为操作数的有效地址
    变址寄存器提供修改量,指令提供基准量(指令执行过中,X寄存器内容可变,D内容不可变)

    用于对线性表类的数组元素进行重复访问

    面向用户,解决程序循环问题

    MOV EAX , 32[ESI]

  8. 基址寻址

    指定一个寄存器来存放基地址,成为基址寄存器B.指令D存放变化的地址值。程序执行过程中B不可改变,D可改变

    CPU内有专门的基址寄存器(EBX EBP)。若基址是EBX,则操作数在数据段,是EBP,则操作数在堆栈段

    • 面向系统,用于程序的重定位(每个用户程序不冲突(编程环境和实际环境))
    • 扩展寻址空间(基址寄存器位数大)

    偏移寻址:相对寻址、变址寻址、基址寻址(以某寄存器的内容与指令中的形式地址字段之和作为有效地址)

  9. 堆栈寻址

    1. 存储器堆栈

      在内存空间中开辟堆栈区

      计算机普遍采用,设置堆栈指针寄存器SP指向栈顶单元,

    2. 寄存器堆栈

      将寄存器作为堆栈

      • 寄存器堆栈栈顶规定,存储器堆栈栈顶随着栈操作而移动
      • 进行堆栈操作,寄存器堆栈数据移动,存储器堆栈数据不移动(堆栈是固定的,数据是活的)
      • 寄存器堆栈速度块,容量有限
      • 寄存器堆栈必须采用专用堆栈指令进行控制
  10. 其他寻址

    1. 变址+间接寻址
    2. 间接+变址寻址
    3. 相对+间接寻址

指令类型

  1. 算数逻辑运算指令
  2. 移位操作指令
  3. 数据传送指令
  4. 堆栈操作指令
  5. 字符串处理指令
  6. 程序控制指令
    1. 转移指令 (有无条件)
    2. 循环控制指令
    3. 子程序调用与返回指令
  7. 输入输出指令
  8. 其他

指令格式设计

CISC RISC

CISC:复杂指令集计算机
RISC:精简指令集计算机(80 -20 )

目的和特点 看书 P.168

不同操作系统中的指令格式,书中有

中央处理器

CPU上电复位后周而复始地取指令、执行指令工作。
具备功能:

  1. 程序控制
  2. 操作控制。产生指令执行过程中需要的操作控制信号,以控制执行部件按指令规定的操作正常运行(执行加法指令运算,CPU必须生成运算器的运算选择控制信号)
  3. 时序控制。严格控制每个操作控制信号的开始时间和持续时间
  4. 数据加工。对数据进行算数、逻辑运算
  5. 中断处理。响应内部异常和外部中断请求(运算异常、缺页、外部设备中断)

组成

主要寄存器

  1. 程序计数器 PC:

    保存将要执行的指令的字节地址,Intelx86叫指令指针寄存器IP.

    PC位宽与主存地址总线位宽相同

    CPU取指令,利用PC的内容作为地址访问主存,并将主存取出的指令字送入指令寄存器中,病修改PC的值以形成下一条指令的地址。

  2. (存储器)地址寄存器 AR:

    保存CPU访问主存的单元地址,无论CPU是取操作还是存数据,都要将访问地址送入AR中。
    位宽和主存地址总线位宽相同,AR并非必须,可将访存地址加载到地址总线上实现

  3. (存储器)数据寄存器 DR:

    存放从主存中读出的数据或者准备写入主存的数据(cache?)

    数据位宽与机器字长相同,并非必须

  4. 指令寄存器 IR:

    保存当前正在执行的指令(而非地址)

    位宽和指令字相同,指令字由指令译码器ID翻译成若干个指令译码信号(每个信号表示一条不同指令,同一时刻只有一个信号有效)
    指令字中的地址码部分由地址生成逻辑对寻址方式进行译码并生成目标地址或数据,根据寻址方式的不同将目标地址送入程序计数器PC、AR和运算部件中 (???)

    并非必须

  5. 通用寄存器组 GR

    运算器内部的若干寄存器 --- 寄存器堆。

  6. 程序状态字寄出去你 PSW/PSR

    保存由算数运算指令、逻辑运算指令、测试指令等建立的各种条件标志。(进位标志、溢出标志、结果为负数、零标志)。还可保存中断和系统工作的状态信息,方便CPU及时了解计算机运行状态

操作控制器

接受指令译码器ID送来的指令译码信息,与时序信号、条件以及状态信息进行组合,形成各种具有严格时间先后顺序的操作控制信号(微操作控制信号序列 --- 控制流),连接到计算机各功能部件的控制端。

按照时间先后打开或关闭某些特定的线路

时序产生器

对完成指令而执行的微操作控制信号进行时间调制,严格规定各信号的产生时间和持续时间

根据时序调制方法不同,操作控制器分为:

  • 硬布线控制器。采用时序逻辑实现,按照同步时序电路设计方法设计,硬时序
  • 微程序控制器。采用程序存储逻辑实现,软时序

指令周期

指令周期:将一条指令从取出到执行完成所需要的时间

阶段:

  1. 取指周期

    CPU以PC的内容位地址从主存中取出指令,并计算后续指令的地址
    (对于变长指令,需要经过指令译码得到实际字节长度后才能计算并修改PC的值)

  2. 译码、取操作数周期

    对指令寄存器的指令字进行指令译码,识别指令类型。(部分实现将译码阶段划分到取指周期中)

    根据指令地址码生成的操作数有效地址(由寻址方式决定),访问相应的寄存器和主存单元。

    对于间接寻址,还需要加入访存周期(间址地址)才能得到操作数的地址

  3. 执行周期

    控制器向ALU及数据通路中的其他相关部件发送操作控制指令,对已经取出的操作数进行加工处理,并将处理的状态信息记录到PSW中

  4. 写回周期

    将运算结果写回到目的寄存器或存储器中,可能需要多个时钟周期

还可能有中断周期、总线周期、IO周期等

便于同步,将指令周期划分成若干个机器周期(CPU周期)
机器周期:从主存中取出一个存储字所需要的最短时间
时钟周期:也称为振荡周期,定义为时钟脉冲的倒数,是计算机中最基本的、最小的时间单位

每个机器周期又包含若干个时钟周期

指令周期的机器周期数和每个机器周期包含的时钟周期数不一定固定

寄存器传送语言 RTL

每条指令的执行过程都可分解为一组操作序列,进而分解为一组微操作序列。
操作:功能部件级的动作
微操作:指令序列中最基本、不可再分的动作

一些问题

CPU多少位指什么?地址总线、数据总线能带来哪些影响

多少位CPU代表的是一次能够从处理多少位的数据,地址总线 != 位数

  • 地址总线:CPU的寻址能力,决定了可直接寻址的内存空间大小
  • 控制总线:传送控制信号和时序信号(读写信号、片选信号、中断响应信号)
  • 数据总线:数据传送能力。CPU->内存/IO 内存/IO ->CPU均可,双向三态形

64位和32位CPU的实质区别?

64 位 CPU 是指 CPU 内部的通用寄存器的宽度为 64 比特,支持整数的 64 比特宽度的算术与逻辑运算

  • 数据处理能力增强:64 位 CPU 通用寄存器的位宽增加一倍,这也就意味着 64 位 CPU 可以一次性处理 64bit 的整形数据;
  • 内存寻址能力增强:如果是 32 位 CPU 的话,它的地址总线最多不会超过 32,那么它所能达到的寻址范围也就不会超过 2 的 32 次方字节(存储单元以字节为单位),也就是 4GB,而如果是 64 位处理器的话,它所能达到的寻址范围理论上就会是 2 的 64 次方字节(上亿 GB)。

一般处理器多少位是指通用寄存器的长度,当然数据线需要与之相同;地址线则不需要与之相等,好比 intel 64 位处理器则是 40 位地址总线,最大支持 1TB 的内存寻址。

注意了,64位操作系统只能运行在64位CPU上

64位CPU装了32位操作系统后寻址能力为什么是4GB

32位操作系统没有对应的64位的寻址指令,不能提供4GB以上的逻辑地址

GPU和CPU的区别

CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂。

而GPU面对的则是类型高度统一的相互无依赖的大规模数据和不需要被打断的纯净的计算环境

image-20211026212402274
image-20211026212402274

GPU采用了数量众多的计算单元和超长的流水线,但只有非常简单的控制逻辑并省去了Cache。
CPU不仅被Cache占据了大量空间,而且还有有复杂的控制逻辑和诸多优化电路,相比之下计算能力只是CPU很小的一部分

image-20211026212600405
image-20211026212600405

**Cache, local memory: CPU > GPU **
Threads(线程数): GPU > CPU
Registers: GPU > CPU 多寄存器可以支持非常多的Thread,thread需要用到register,thread数目大,register也必须得跟着很大才行。
SIMD Unit(单指令多数据流,以同步方式,在同一时间内执行同一条指令): GPU > CPU。

  • CPU时延低:有强大的ALU(算术运算单元),它可以在很少的时钟周期内完成算术计算。时钟周期的频率非常高。复杂的逻辑控制单元可以确保当程序含有多个分支的时候,它通过提供分支预测的能力来降低延时。
  • GPU基于大的吞吐量设计:GPU的特点是有很多的ALU和很少的cache. 缓存的目的不是保存后面需要访问的数据的,这点和CPU不同,而是为thread提高服务的。如果有很多线程需要访问同一个相同的数据,缓存会合并这些访问,然后再去访问dram(因为需要访问的数据保存在dram中而不是cache里面),获取数据后cache会转发这个数据给对应的线程,这个时候是数据转发的角色。但是由于需要访问dram,自然会带来延时的问题。

CPU擅长逻辑控制,串行的运算。和通用类型数据运算不同,GPU擅长的是大规模并发计算

GPU大部分工作计算量大,没啥技术含量,重复很多次。并行计算(流水线,无法单独工作,必须由cpu控制)

参考 知乎open in new window