计算机组成
-1 蛤?
1个字节(byte)= 8位(bit)
32位系统中,1 字 = 4 字节;64位,1 字 = 8 字节
在 MIPS 指令集中可以用来实现跳转到 4GB 空间内任意地址的指令是 jr
j:可跳转226+2=228个地址单元,即228+3bits = 256 MB
beq:256 KB
0 绪论
冯诺依曼架构
计算机应由运算器、控制器、存储器、输入设备和输出设备五个基本部件组成。
存储器不仅能存放数据,而且也能存放指令,形式上两者没有区别,但计算机应能区分数据还是指令;控制器应能自动取出指令来执行;运算器应能进行加/减/乘/除四种基本算术运算,并且也能进行一些逻辑运算和附加运算;操作人员可以通过输入设备、输出设备和主机进行通信。
抽象
文件是对 I/0 设备的抽象
虚拟内存是对程序存储器的抽象
进程是对一个正在运行的程序的抽象:是在给定数据集上的一次程序执行
并发并行
并发: 逻辑上的并行,物理上交替执行(使系统能够同时处理多个任务)
并行: 物理上的并行(使系统真正地运行更快)
1 数制与运算
进制
进制转换
补码
补码取反加一 0011 → 1101 (3 → -3) 取反加一和减一取反效果一样
反码只取反,原码只改符号位
补码运算
[X+Y]补= [X]补+ [Y]补,[X-Y]补=[X]补+[-Y]补
3+4 = 7 0011+0100 = 0111
3-4 = -1 0011+1100 = 1111
浮点数表示
阶码:01000 尾数:0.10110010001
178.125 = 10110010.001 = 0.10110010001 * (2^01000)
浮点数规格化
数符 S: 1位,0表示正数,1表示负数
阶码 E:用移码表示,n 位阶码偏移量为 2n-1-1
如8位阶码偏移量为 7FH(即127), 11位阶码偏移量3FFH(即1023)
尾数 M: 尾数必须规格化成小数点左侧一定为1,并且小数点前面这个1作为隐含位被省略。这样单精度浮点数尾数实际上为24位
计算: 1.m * 2^(E-127) 如果是双精度,是E-1023
E一定要先减
2的-126 ~ 127次方
大端小端
大端存储模式:数据的低位保存在内存中的高地址中,数据的高位保存在内存中的低地址中;
小端存储模式:数据的低位保存在内存中的低地址中,数据的高位保存在内存中的高地址中;
各种编码表示10进制
8421:正常,0=0000 1=0001 2=0010 3=0011 4=0100 … 9=1001
5421:… 3=0011 4=0100 5=1000 … 9=1100 ; 而0101是禁止码
2421:… 4=0100 5=1011 6=1100 7=1101 8=1110 9=1111
余3:每个字符编码比相应的8421码多3,0=0011 1=0100 2=0101 3=0110 … 9=1100
不是重点,但是挺逆天的
逻辑代数
按位或:“|”
按位与:“&”
按位取反:“~”(单目运算)
按位异或:“^”
左移:高位移出,低位补0。可能溢出!
右移:低位移出,高位补符,可能发生有效数据丢失。
与:F = A·B ,F=AB 或者 F = A∧B
或:F = A + B 或者 F = A ∨ B
异或F=A 圆中间一个十字B
同或F = A⊙ B
对偶定理:将原函数F中的全部 “•” 换成 “+”,“+” 换成 “•”,“0”换成 “1”,“1” 换成 “0”,所得的新函数就是原函数的对偶式,记作F’或F*
由n个变量组成的 “与” 项中,每个变量以原变量或反变量的形式出现且仅出现一次,则这个与项称为最小项
n个变量有2^n个最小项
全部由最小项构成的与或式,也称标准与或式
简化公式
吸收率1
吸收率2
2 数字逻辑
组合逻辑
从结构看,组合逻辑电路由门电路构成,不含 反馈电路 ,也不含 存储电路 ,信号从输入开始单向传输到输出。对于组合逻辑电路,任何时刻电路的输出仅由当时的 输入信号 决定
半加器
全加器
溢出
“00”表示正,“11”表示负,如果运算结果符号位出现“01”(正溢)或“10” (负溢)都表示出现溢出
6 = 0110 7 = 0111 6+7 = 01101,正溢出
-6=1010 -7=1001 -6-7 = 10011,负溢出
-3 = 1101 -3-3 = 11010 负数不溢出
数值比较器
ALU
操作数,选择数
编码器
某一个输入端的信号变换成相应的一组二进制代码输出的过程叫做 编码
74147优先编码器(谁优先输出谁)
译码器
将二进制代码所表示的信息翻译成对应高低电平信号输出的过程称为译码
3线-8线译码器(74138)
3个输入:A2,A1,A0;000~111共8种输入组合。
8个输出:Y7~Y0,低电平输出有效;任何时刻最多只有一个输出有效。当输入为000时,Y0输出有效;当输入为001时,Y1输出有效。
3个使能控制:S0,S1,S2 为使能输入,仅当它们分别为1、0、0时,译码器才正常译码;否则禁止工作。
多路选择器
若D7-D0 = 10100101
Y = m7+m5+m2+m0
竞争冒险
竞争
某个输入变量通过两条或两条以上的途径传到输出端,由于每条途径延迟时间不同,到达输出门的时间就有先有后
冒险
门电路因输入端的竞争而导致输出端产生不正常的尖峰干扰脉冲信号(毛刺)的现象
A+ !A 存在0冒险 A ·!A存在1冒险
卡诺图法判断
在逻辑函数的卡诺图中,函数的每个与项对应卡诺图上的一个卡诺圈,若两个卡诺圈相切,相切处将存在冒险。
增加冗余项。
L=AC+ ̅AB,当B=C=1时, L=A+ ̅A,存在冒险。增加冗余项 L=AC+ ̅AB+BC,逻辑函数功能不变,冒险消除。
时序逻辑
锁存器和触发器
锁存器是电位(电平)触发的,只有在时钟CP有效电平(高电平CP=1或者低电平CP=0)期间,触发器的状态才有可能发生变化。
触发器的状态变化只发生在时钟CP的有效沿(上升沿或者下降沿)期间,CP=1、CP=0时触发器的状态不会发生变化
D锁存:CP=0保持;CP=1置为D的值
D触发器
D触发由2个D锁存组成;CP从0到1触发
加使能EN:EN=1正常,EN=0一直保持
JK触发器
J0K0,输出不变; J0K1,输出为0; J1K0,输出为1;J1K1,输出反转
状态机
Moore
输出信号仅与当前状态有关
Mealy
输出信号与当前状态及输入信号有关
状态转移表长这样
移位寄存器
脉冲一次移位一次
计数器
同步
同步计数器
异步
时钟同步?
Tccq:触发器时钟到Q的最小延迟
Tcd:组合逻辑的延迟
3 汇编
寻址
立即寻址
操作数直接在指令代码中给出。addi $s1, $s2, 100
寄存器直接寻址
操作数在寄存器中,指令地址字段给出寄存器的地址 add s2,$s3
寄存器间接寻址
操作数在存储器中,指令地址字段中给出的寄存器的内容是操作数在存储器中的地址 lw s2)
基址寻址
操作数在存储器中,指令地址字段给出一基址寄存器和一形式地址,基址寄存器的内容与形式地址之和是操作数的内存地址 lw s2)
变址寻址
操作数在存储器中,指令地址字段给出一变址寄存器和一形式地址,变址寄存器的内容与形式地址之和是操作数的内存地址 lb t0)
相对寻址
基址寻址的特例,由程序计数器PC作为基址寄存器,指令中给出的形式地址作为位移量,二者之和是操作数的内存地址。beq $s1, $s2, 100
堆栈寻址
压栈SP -= 4;出栈SP += 4;
指令
指令类型 R/I/J
R:两个寄存器运算,结果存到第三个
I:有1个符号立即数
J:跳转,26位跳转地址
指令格式
R-Type
OP永为000000
add:
逻辑左移sll t2,10也是R型,10存在Shamt里;sllv $t1, $t2, $t3
jr $t1 # PC = $t1
I-Type
rt ← rs + immediate
rt ← memory[base + offest]
if (rs = rt) then PC ← PC + sign_extend
J-Type
j直接跳转
jal 指令的意思是跳转到对应标签的位置,并将当前执行的指令位置存储在 $ra 寄存器中。
各种指令
1 | 赋值 |
4 MIPS处理器
MIPS模型机
寄存器,32位虚拟地址
组合部件ALU(逻辑运算)、MUX(多路选择器)Signext(符号扩展)
寄存器堆:两个32位数据输出端口,一个32位数据输入端口,三个5位寄存器地址输入端口
边沿触发的时钟同步方法
单周期处理器
哈佛体系结构:使用指令存储区(IM)和数据存储区(DM)分别保存指令和数据
取指令
32位Instruction = IM[PC],PC+4,
R型如add
lw
sw
寄存器堆写入端地址选择MUX,选择控制信号 RegDst
ALU输入端B数据源选择MUX,选择控制信号 ALUSrc
寄存器堆写入端数据源选择MUX,选择控制信号 MemtoReg
beq
PC输入端数据源选择MUX,选择控制信号 PCSrc
控制信号
Op:控制7个控制信号
Func:仅用于R型,控制ALUop
RegDst
R型指令:RegDst=1,选择Rd
Lw指令: RegDst=0,选择Rt
其他指令:不关心
ALUScr
R型指令:ALUSrc=0,选择寄存器堆的 Read data2 输出
Lw Sw指令: ALUSrc=1,选择Signext的输出
Beq指令(减法运算): ALUSrc=0,选择 Read data2 输出
MemtoReg
R型指令:MemtoReg=0,选择 ALU 输出
Lw指令: MemtoReg=1,选择数据存储器DM输出
其他指令: 不关心
Branch
Beq指令:Branch=1,此时若Zero=1,PC输入选择加法器Nadd输出(分支指令目的地址),否则选择加法器Add输出(PC+4)
其他指令:Branch=0,PC输入选择加法器Add输出(PC+4)
ALU控制信号
ALUOP:10,00,01,分3种情况,10再看FUNC字段,00做一个加法,01做一个减法
单周期过程
R 取值-读寄存器-ALU运算-写寄存器
lw 取值-读寄存器-ALU运算-读数据-写寄存器
多周期流水线
五个阶段
-
取指-IF: 取指, PC自增
-
译码和读寄存器-ID:译码, 读寄存器
-
执行-EX: 执行(ALU) Lw/Sw指令: 计算内存指针 其他指令: 执行其他算术和逻辑运算
-
访存-Mem: Lw: 从内存读数据到CPU寄存器 Sw: 把寄存器的值写到内存中
-
回写-WB: 把数据写回到寄存器中
当时钟上升沿到来时,组合逻辑计算结果写入后级寄存器
线路
增加新MUX
指令相关
针对寄存器
读后写,写后读,写后写
指令冲突
只有写后读会有指令冲突
流水线冒险
结构冒险:资源竞争,要使用的部件正在忙
数据冒险:指令执行所需的数据暂时不可用而造成的指令执行的停顿
控制冒险:也称为分支冒险,必须根据前一条指令的执行结果才能确定下一条真正要执行的指令地址
结构冒险
内存:流水线的数据通路需要将指令和数据分别存储
寄存器:将寄存器组的使用权限分为两部分,一个时钟周期内前半个时钟周期进行写操作,后半个时钟周期进行读操作
在同一个时钟周期,可以同时进行读寄存器和写寄存器的操作
数据冒险
旁发
阻塞
阻塞+旁发
阻塞等同插入nop指令
条件:IF/ID的前序是lw指令,并且lw的rt寄存器与IF/ID的rs或rt相同
- 冻结IF/ID:sub继续被保存(用寄存器的使能)
- 清除ID/EX:指令全为0,等价于插入NOP(用寄存器的CLR清除)
- 冻结PC:防止PC继续计数,PC保持不变
1 | sub $t2,$t1,$t3 |
如果有转发电路,
1 | lw $t2, 4($t0) |
需要插入几个NOP指令?1个
有转发的完整流水线
控制冒险
阻塞或者赌博不跳转
还可以在ID前放置比较器
计算机性能
响应时间:从提交作业到完成作业所花费的时间
吞吐量:一定时间间隔内完成的作业数
5 主存
工作原理
RAM
随机存取存储器(RAM)
(T是MOS管)
读出:D 线先预充电到 Vpre=2.5V,然后字选线高电平,T导通
若电路保存 信息1,Vcs=3.5V,电流方向从单元电路内部向外
若电路保存信息 0,Vcs=0.0V,电流方向从外向单元电路内部
写入操作:D 线加高电平(1,3.5V)或低电平(0,0V),字选择线置高电平,T导通;
写1时,D线高电平,对Cs充电;
写0时,D线低电平,Cs放电;
ROM
只读存储器(ROM)
PROM
出场时为1,当写入0烧毁熔丝,不可恢复
紫外线擦除可编程的EPROM、电擦除可编程的EEPROM单元电路可以恢复
内部结构
芯片容量:2^n * m
地址线:n位
数据线:m位
这里就是n个字单元,每个字单元m位,很重要
1024×2
二维地址结构:
4096 × 4,4096×4 = 2^14
存储:2^7 * (2^5*2^2);一行4个单元一组为一个字,一行32个字
妙哇
存储器扩展
位扩展
1K * 4 扩展为 1K * 8:
字扩展
1K * 8 扩展为 4K * 8:
混合扩展
4Kx4扩展16Kx8
ROM、RAM扩展
符号表示
符号表示
读单元地址:Address;读控制信号:MemRead;读出数据:Readdata
写单元地址:Address;写控制信号:MemWrite;写入数据:Writedata
DRAM刷新方式
D线上加感应放大器
读1时D线电压
读0时D线电压
传感放大器会刷新Cs,让Cs保持原来状态而不是被破坏
分散刷新
一个存储周期分为两段: 前一段用于正常读写,后一段用于刷新操作
分散刷新间隔 = 刷新行数×存储周期 = 刷新周期
集中刷新
集中刷新间隔 = 刷新周期
异步刷新(最常用)
一个刷新周期内将存储芯片内的所有行刷新一遍,且只刷新一遍
以128行为例,在2ms时间内必须轮流对每一行刷新一次,即每隔2ms/128=15.5μs刷新一行。这时假定读/写与刷新操作时间都为0.5μs,则可用前15μs进行正常读/写操作,最后0.5μs完成刷新操作
异步刷新间隔 = 刷新周期
6 高速缓存
数据块(block):Cache与主存的基本划分单位,也是主存与Cache一次交换数据的最小单位,由多个字节(字)组成,取决与主存一次读写操作所能完成的数据字节数。也表明主存于Cache之间局部总线的宽度。
标记(tag):Cache每一数据块有一个标记字段,用来保存该数据块对应的主存数据块的地址信息。
有效位(valid bit):Cache中每一Block有一个有效位,用于指示相应数据块中是否包含有效数据。
行(line ):Cache中 一个block及其 tag、valid bit构成1行。
组(set):若干块(Block)构成一个组,地址比较一般能在组内各块间同时进行。
路(way):Cache相关联的等级,每一路具有独立的地址比较机构,各路地址比较能同时进行(一般与组结合),路数即指一组内的块数。
命中率(hit rate):目标数据在Cache中的存储访问的比例。
缺失率(miss rate):目标数据不在Cache中的存储访问的比例。
分S组,每组E行(Block, 数据块),每数据块包含B个字节
Cache的容量:N *( B * 8+tag位+1(valid))bits
映射
全相联
主存中的某一Block可以映射到Cache中的任意一Blcok
主存地址格式:
CPU找Cache中地址时,与所有Tag进行比较
灵活,成本高
直接映射
主存中的某一块 J 映射到Cache中的固定块 K, K = J Mod C, 其中C是Cache包含的块数
相当于一路组相连
主存地址格式
区内索引数量 = Cache行数
Cache如果有16行 = Index有4位
区数量为主存行数/一个区内数量
例:主存容量1M字节,Cache容量4k字节,Block大小256 Bytes
Cache: 2^12 ÷ 2^8 = 2^4 Blocks,Index应该为4位
主存: 2^12 Blocks,每个区2^4Blocks , 分成2^8个区
主存地址:20位,其中高 8 位区地址,中间4位为区内块地址,低8位为块内地址。
组相联
主存和Cache 都分成 K 组,其中Cache每组包含 L 块数据(Nc= K * L),主存每组包含M块数据;主存的块 J 以下列原则映射到 Cache 的组 I 中的任何一块(Nm= K * M) 。 I = J mod K (0 ≤ I ≤ K)
主存地址格式
Cache:valid,Tag,Data
在组相连中,如果只有一组,则变成了全相联了。
如果组相联中每组只有一个数据块,则组相联就变成直接相联了。
替换策略
缺失处理方式
替换方式
FIFO:最先装入数据的块被替换
LRU:最近最少使用法
访问命中时,所有块的计数值与命中块的计数值进行比较:如果某块计数值小于命中块的计数值, 则该块的计数值加 1;如果该块的计数值大于命中块的计数值,则数值不变。最后将命中块的计数器清为0。
访问未命中,需要替换时,则选择计数值最大的块被替换(若最大值并列,随机选择一个)。被替换块的计数器清0,而其它的计数器则加1
性能分析
一般情况增加路数提高命中率,降低时间;
随着块大小增加,缺失率先降低后增加;
Cache所需总存储容量=(tag位+有效位+(可能的脏位)+1个数据块容量)* 块数
命中率 * Cache访问时间+(1-命中率)* (装入Cache+Cache访问时间)
写回(Write Back):写操作只更新Cache中的数据,直到Block替换时才将整个Block写回主存,一般使用“脏位”(dirty bit)来表示Block在替换回主存之前是否被修改过;
要点?
内存地址格式: 组内块地址(多少b) + 组地址(多少b) + 块内偏移地址(多少b)1
7 虚拟存储
把主存当做辅助存储器的高速缓存技术,称为虚拟存储技术,程序中可以使用较大的存储空间称为虚拟存储器
固定长(简单)分区,浪费空间
可变长分区,开始好,后面会产生空块
页式虚拟存储器
内存分成定长小块(页),进程也分成定长小块。
虚存页称为虚页,主存页称为实页
一个进程用很多小块,可以不连续
操作系统为进程生成页表
通过页表实现逻辑地址向物理地址的转换。
页表基址寄存器:保存页表在内存中的首地址
虚实地址的转换
-
根据虚地址,访问主存中的页表
-
根据实地址,访问主存中的物理页
多级页表
二级页表页面大小为4KB的2GB虚拟存储器,每个页表项占4个字节:2^19 * 2^2=2MB
一级页表2^9项(每项占4个字节),二级页表2^10项(每项占4个字节),整个一级页表常驻内存,常用的两个活跃二级页表装载到内存: 512 * 4+2 * 1K * 4 = 10KB (假定2个活跃页表换入内存时,实际占用的内存)
例题
快表TLB
使用Cache存储部分活跃的页表项,称为TLB(快表),它包含了最近使用的那些页表项。
TLB内容:标记(虚页号)、数据块(实页号)、有效位、修改位。
TLB一般采用全相联或者组相联
TLB命中与否 与Cache是否命中 无关
8 链接
目标文件的三种格式
- 可重定位目标文件(relocatable object file: .o )
包含二进制代码和数据
其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件
每一个 .c 源文件产生一个对应的 .o 文件
- 可执行目标文件(executable object file)
可以没有扩展名(Linux)或者 a.out ; .exe(Windows)
包含二进制代码和数据
其形式可以被直接复制到内存并执行
- 共享目标文件(shared object file)
一种特殊类型的可重定位目标文件
可以在加载或者运行时被动态地加载进内存并链接
windows:.lib (静态链接库) .dll (动态链接库);Linux:.a(静态链接) .so(动态链接)
Elf格式
.text: 已编译程序的机器代码(Code)
.rodata: 只读数据
.data: 已初始化的全局和静态 C 变量
.bss: Block Started by Symbol
.symtab: 符号表
.rel.text: .text 节的重定位信息
.rel.data(.rel.data.rel): .data节的重定位信息
链接器符号
- 全局符号
由模块 m 定义并能被其他模块引用的符号:非静态的 C 函数和全局变量
- 外部符号
由其他模块定义并被模块 m 引用的全局符号:在其他模块中定义的非静态 C 函数和全局变量
- 局部符号
只被模块 m 定义和引用的符号:带 static 属性的 C 函数和全局变量
**局部链接器符号和局部变量不同 **连接器不知道局部变量
局部非静态C变量:保存在栈上或寄存器中
局部静态C变量:保存在 .data 或 .bss
符号解析
局部符号
在相同模块中定义和引用
编译器只允许每个模块中每个局部符号有一个定义
其解析简单明了
全局符号
符号在当前模块中无定义:编译器会假设该符号是在其他某个模块中定义的,生成一个链接器符号表条目,并把它交给链接器处理
如果链接器在它的任何输入模块中都找不到这个被引用符号的定义:输出一条错误信息并终止
还有一种情况:多个目标文件可能会定义相同名字的全局符号
- 全局符号分为强符号和弱符号
强符号:函数和已初始化的全局变量
弱符号:未初始化的全局变量和外部符号
-
不允许有多个同名的强符号:每个强符号只能定义一次,否则链接错误
-
如果有一个强符号和多个弱符号同名,那么选择强符号
-
如果有多个弱符号同名,那么从这些弱符号中任意选择一个
静态库
ar rcs name.a name1.o name2.o :创建静态库
gcc -static -o test test.o ./name.a :链接静态库
链接去年好像没考😅
9 总线和IO
总线仲裁
链式查询方式
总线控制器(仲裁器)收到总线申请BR,BG(总线同意信号)逐个往下传;
到某接口有总线申请(BR:总线申请信号),BG停止往下传;
该接口获得总线使用权,并建立总线忙信号BS。
计数器定时查询方式
总线控制器(仲裁器)收到总线申请BR,仲裁器上的计数器开始计数;
当某个有总线申请的设备地址与计数器一致,便获得总线使用权,并建立总线忙信号BS
独立请求方式
每个设备有独立的请求信号和总线同意信号;
总线控制器根据设备的优先级决定将总线的使用权交给哪个设备。
IO
I/O地址(I/O接口地址, I/O端口地址):实际上是I/O接口电路中寄存器的地址(外设寄存器)
??
程序查询IO
编程式I/O
控制命令:激活外设完成动作。如指示磁带机快进或快退,控制命令与设备类型相关;
测试命令:测试与I/O接口及其外部设备的各种状态条件;
读命令:使I/O接口从外设获得一个数据项,存入内部缓冲区;
写命令:使I/O接口从数据总线获得一个数据项,然后传送到外设。
- I/O操作由CPU直接完成(通过执行I/O指令完成)
- 外设速度慢,CPU速度快,在外设准备过程中,CPU处在不断的查询之中,CPU的效率浪费严重
- 外设与CPU完全串行工作
中断IO
顾名思义
DMA
DMA控制器接到DMA应答信号后,通过控制逻辑向系统总线发送存储器地址信号、存储器读写控制信号、I/O接口读写控制信号等,完成一次数据传送。
若是单字传输,一般仅需要一个总线周期,所以这种方式称为周期窃取(cycle-stealing,或者叫周期挪用)方式。若是成组传输,需要多个总线周期来完成。所有数据传送结束后,通过中断方式告知CPU进行善后处理。
CPU仅在开始DMA操作之前和完成DMA操作之后参与I/O处理,在DMA过程中,CPU可以运行原来的程序
停止CPU访问内存(成组传送方式)
一次DMA请求得到响应后,DMA控制器完全占用总线,进行块数据(多字)传送,直到所有数据传送完毕才释放总线,这段时间完全停止CPU访问内存。
适应高速外设与存储器交换数据的情况。
周期窃取方式(单字传送方式,DMA和CPU交替使用总线)
每次DMA请求得到响应后,DMA控制器窃取一个总线周期完成一次数据传送,然后释放总线,CPU接着使用一个总线周期,然后DMA再窃取一个周期,这样持续循环下去,直到数据传输结束。
一般情况下,CPU 不访问存储器时释放总线
一般适应存储器速度远高于I/O设备速度的情况。