导论
01 计算机系统概述





f/v:每秒包含的CPU时钟周期数

CPI:指令所需的时钟周期数

基准程序:对于不同应用可能要不同的计算机

转换成MIPS再计算!!对计算机而不是程序作对比分析
02 计算机顶层视图
CPU

- CPU频率不能无限提高
- 改进CPU芯片结构
- 内存墙的存在
- 采用高速缓存
- CPU等待I/O传输数据
- 采用中断机制
存储器

- 兼顾存储容量、速度和成本
- 层次式存储结构
I/O设备

- I/O设备传输速率差异大,跟不上CPU性能的提升
- 设立缓冲区
- 新的接口技术
- 不同的I/O操作技术
总线

- 计算机部件互连复杂
- 采用总线
03 数据的机器级表示
整数的二进制表示

补码是平移,移码是镜面。

浮点数的二进制表示
信息量相同(2^k),精度和表示范围的取舍。(小数要精度,大数要范围)


二进制编码的十进制表示
浮点运算有精度限制、转换成本高等问题,而应用需要长数字串计算,引入BCD码直接计算。

04 数据校验码
奇偶校验码


海明码
设计:先确定长度,再确定参与的位。

不是M越大越好?因为M越大假设越可能不成立。

将位设置在与其故障字值相同的位置。

C‘直接从D’中取出,C’’通过D‘重新计算。
循环冗余检验
适合传输大量数据


先生成k位校验码,再跟在M位数据后面除以生成多项式,看是否能整除。
问传输后接收的数据:不需要包括校错。
中央处理器(CPU)
ALU
05 整数运算
加法


速度慢,因为要递归到C0->全先行进位加法器


全先行复杂,取得计算时间和硬件复杂度的权衡->多个CLA串联


OF=Cn xor Cn-1
CF=Cin xor Cout Cout=Cn 如果做减法要取补码则Cin=1 否则为0
减法

变成加法,把Y取补码:
多路选择器把Y按位取反,X和Y取反相加,但这不是补码?此时C0=1 则为补码
Sub信号为0,上面的路通;信号为1,下面的路通;
还连接到ALU的C0:如果为0,C0=0,X+Y;如果为1,C0=1,X+~Y+1
乘法
包括无符号-手工演算、带符号-布斯算法

手工演算:n*n 用2n位表示结果 硬件要覆盖2n长度
1、部分积:一位乘以所有,或两位乘以所有再相加,类推… 一步步叠上去
2、部分积左移改成原来的结果右移
3、0不需要乘,做右移就够了

红:参与运算 黑:不参与运算
反复进行右移、加、右移、加…

n位ALU:只储存进行运算的数字
刚开始右边寄存器Y为空 浪费 所以把Y存入这部分空间(右边n位寄存器)
Y和运算结果可放在一起:乘完就不需要,用过的位置被剔除
控制逻辑决定:先加再右移(1)还是直接右移(0)

红:部分积 黑:乘数Y 节约空间巧妙
无符号用该方法计算:注意+被乘数所得的溢出位应被保留!(因为右移代替左移)

变成原码后,符号位用异或获得,然后将结果转换成补码 但这消耗大量计算资源,速度慢

把Y表示出来 Y0因为防止落单而补充
红框式:求和式 可作为迭代的运算方式
2*(-1)表示右移一位 Pi+1表示已经右移后的结果
其实只改了绿框:以前是 X*Yi 绿框在0的基础上多了-1的可能性


Y0=0补了状态
0:右移 -1:-X 1:+X 最后把Y0舍去 106!=42 问题出在补充位!!补1而不是0!!

原来是0补0,原来是1补1,补充位和原来相同 因为右移是除以2的操作——应保持符号不变
适用于有符号数:如果无符号想用,要在1前面补0以示区别 所以没必要用这个方法

Yi*Xi可通过一个与运算替代
除法
包括无符号-手工演算、带符号(恢复余数、不恢复余数)


位数不够就上0

余数取低n位

除数右移,看余数减去除数够不够减,够减时从余数减掉,结果上在商里(1:够 0:不够)
最后余数只有低位有用
实际上参与运算的长度只有n位,但放了2n位,造成了浪费
这里的此消彼长:有效的余数长度变短、商的位数变长

高位专门存余数,低位刚开始是余数,后来是商——除数右移替换成余数左移 所以除数不变了
刚开始余数分开放在了 余数和商 里

看余数的4位够不够减除数,够减上1,不够减上0 但是上面没有考虑同号异号问题

-7/3=-2余-1(-3余2是错误的!!!!!)
余数-除数后符号不能改变(-1-3符号不变,2-3符号变化)
目标是:余数绝对值不断变小但符号不改变
余数符号不变:够减;符号变化:不够减
左移、减除数判断是否够减(和余数符号是否相同)、左移、判断是否够减..
除数和被除数异号:商要取反加一(看最开始的0011与1001是否异号)

没办法判断够不够,先加减除数再看要不要恢复(两栏余数的符号是否一致) 够减上1,不够减上0
这里除数和被除数异号,所以商要取反加一
思考:余数左移过程中可能变号吗?采用刚开始的符号还是什么?因为是乘2,应该采用开始的吧

恢复、撤销成本高如果有错误:在下面的过程中恢复 不恢复余数除法思想
左移(乘以2)然后减除数Y 不够大的做+Y操作(加法弥补不够减的偏差、同号后的减操作)因为+Y不影响结果

区别:先上1/0,再左移
最后处理商和余数的方式:


余数和除数符号相同:左移减 先左移得到0101 0011 再减R=0101-0011=0010
商:1110左移一位:1101 再加1:1110
余数0010与被除数1001符号不同,被除数1001与除数0011符号也不同:余数-除数=0010-0011=1111
思考:有一些结果算不对?余数中途或最后为0,直接在商+1,再补0

这里就是所谓的异常情况,就是余数和除数的绝对值关系
06 浮点数运算
加法和减法
大的变小:尾数左移时高位可能丢掉
小的变大:尾数右移时低位可能丢掉,但影响没有高位大 即使保留下来可能在32->23尾码的过程中损失
这里如果是规格化数,尾数会补上符号位,再进行移动,即sig_a |= 0x800000;


减法变加法:符号位取反
X=0或Y=0 把另一个赋给结果
均不为0:看阶码是否相同
- 如果相同+尾数
- 如果不同 把小的阶码变大 将尾数右移(此处循环)
- 特判:尾数是否为0?因为阶码可相差253,但尾数只有24位 如果全0了直接把另一个数赋给结果
4.阶码相同后进行Signed带符号尾数的相加(符号位+尾数 若为相反数则一定为0)
如果加后为0,说明是相反数,此时调整阶码为0使结果为0,才有Z为0(如果不调整为1.02^阶码)*指数清零
隐藏位参与运算 若尾数溢出(是否有进位)则尾数右移 阶码加1 如果尾数0开头要左移阶码减
- 若太大(Exponent=255):正负无穷 Report:尾数清零
- 若太小:变成非规格化数 注意移码变为126
5.如果阶码处理完毕,开始处理尾数:
需要先判断隐藏位为1但是阶码为0的情况:非规格化数->规格化数 把阶码从0变为1就变成规格化数了
若隐藏位不为1(尾数此时是24位)尾数左移(使1为首位)阶码减1
- Report underflow: 阶码减到0时注意尾数要右移一次(127->126) 规格化数->非规格化数
原码加法

做减法:不够减:先借一个1,如果有进位,借的位可以忽略不计;如果没进位说明还不回去
乘除法(尾数部分利用无符号乘除)

先弄阶码:Subtract bias:从阶值的和中减去一个偏移量-127
阶码是否上溢:正负无穷
价码是否下溢:非规格化数
乘尾数:直接乘(规格化)

无符号乘法:遇见0就移位,遇见1就加

除法余数出现全0:是够减还是不够减

精度考虑
三个保护位提高精度 有时候也不一定 看舍入方式
07 二进制编码的十进制数运算

到了10没到16进不上去:希望逢10进1,此时逢16进1,补6
到了16(16、17、18、19):多消耗了6,补6 (进位依然参与运算)
10-19需要调整 9=10+9 有一位进位时

- 取反-6
- +6取反
存储
08 内部存储器

地址空间:房间(地址)的集合 楼里面几个房间
寻址能力:一次能找几个房间(地址) 投递员认识几个房间
32位系统访问4GB(2^32) 对科学计算不够 怎么增加内存条?房间数不能增加,增加房间人数
为什么让普通的字节寻址,而不是64位寻址?

外存不属于冯诺依曼结构,冯诺依曼的存储器指主存

存储刚开始是磁芯

控制信号 先选中位元,然后再给控制信号说是读还是写

只读存储器能写:毕竟至少写一次 写完一次就不能写了
RAM
最先产生,所以由此命名(其实其他都能随机存取)
易失的:断电时突然没有 通电时可擦除
随机:读写所需要的时间与这段信息所在的位置或所写入的位置无关。
-

电量不会一成不变,如何保证漏电不会漏没:定期维护充电 刷新指处理到理想状态(可充电可放电)

RAM:易失的 断电后数据依然会丢失
好处:有电时不需要被刷新 刷新时不能正常访问内存,有可能影响访问(变慢)
坏处:体积变大,集成度降低

SRAM更快,因为容量较小所以放在金字塔上方


读写速度会变快
ROM

是随机的 可以读但不能写入新的数据
非易失,不可以被修改(有好:只要写入就一直在那里 有坏:写错了)

可以用电来写
PROM是成批生产的,当需要的ROM数量较小时,使用PROM(电)比制作专门的掩膜ROM更经济,而且有利于缩短制作周期。
用户可以按照自己的需要写入数据,即对PROM编程。
RMM

主要读不等于不能写 可读可写!!

把原来的消掉,再写进去(可多次改写)
擦比较局限:时间长、所有东西都要擦(不能保留写对的)

和上面的区别:擦除用电而不是光 不会删除之前的内容 ROM都是非易失
坏处:贵、集成度低、可以在线修改所以可靠性不高




内存条->内存系统
问问题:
插黄的插红的 什么东西
内存空间增加扩大容量:字扩展

同一个地址的存储位置放着多个位元,构成一个存储单元。访问的最小的单元。
放多少个位元:寻址模式。一个字:多个字节。如64位:8个字节。

串、正方形、还是窄窄的矩形?排成正方形。
串不好:选中一个寻址单元需要100根线,10*10就只需要20根线(不复用),有利于构筑存储阵列。
箭头:有一根线相连。选中的方法:“交叉”所在行列的线会被加电。
行译码器、列译码器:如何确定哪根线被加电。
地址缓冲器:对应2048,11位地址线可复用,先用来传行地址,再用来传列地址,行列地址都有后就可以解析。
数据:放大器用来输入输出
刷新:内存主要是DRAM 电容的电量会自然丢失,不刷新状态就不能长期保持稳定,所以要不断地刷新
地址线是从主存获取行和列信息交给行地址缓冲器和列地址缓冲器的,可以复用。
而行译码器和列译码器不能复用,否则不可能唯一标识出来单元。所以上面需要11+11=22根线

2^3=8,所以用3位地址来选片。片内地址log2(16*2^20)=24(行+列吧)最后得27=24+3.


1、字扩展:4个芯片地址变了,需要选地址。2个选片位。16K=2^4*2^10,所以片内地址14位。
2、位扩展:虽然有8个芯片,但增加的是位数而不是地址,所以不需要标识芯片(地址范围一样)。2^12,全部为片内。
3、同时:4个芯片地址变了,需要选地址。依然是14位片内地址。


n位地址变成2^n种输出,把线设为1

给电容充电:电容(主存)不能访问。一会工作一会不工作。所以刷新影响寄存器工作(数据都在主存里读写)
- 集中式刷新:停止所有,刷新每一行,需要时间。对系统影响很大。(看有几个)
- 分散式刷新:分散到每一次存储周期(读写操作)。完成一次进行一次刷新。整个刷新时间一样,不过分散到每一个周期。没有明显暂停,就是变慢了,但一直可以访问。
- 异步式刷新:设了一个间隔,间隔内保证每一行被刷新一次,具体什么时候刷新根据这一行被不被读写来定。

引脚:小白点,为了可访问

正反八个芯片(内存条),组织在一起其实是对容量进行了扩展。
- 位扩展:寻址单元个数没有变,改变里面的位数,即寻址模式。地址线决定有多少行和列。原来1根现在8根数据线
- 字扩展:改变个数,但不改变位数。4倍增加一条线(复用),两条线(不复用)。
- 字、位同时扩展:同上。

把内存条插入插槽,就可以互相协作。四个内存条是字扩展:依然是字节寻址,说明访问的存储单元数量变多了。
09 高速缓存存储器(Cache)
目的、基本思路、工作流程
比主存更靠近CPU.速度更快,为了解决内存墙


可以给CPU提供数据和指令。可以在主板在,也可以在CPU内部(主要)。
存放的依然是主存里的信息,是部分信息的副本。
需要的信息不在Cache中怎么办?
不能把Cache和主存一样大:DRAM SRAM 成本上的激增,集成度低相同容量大

Hit:绿色 可以快速返回
Miss:从主存中读块,然后把所需要的的字传给CPU


1、Cache中内容和位置都有。不看内容,检查位置在不在,遍历地址(标记)一一核对
2、3、照理来说容量非常小,所以大部分时候未命中,时间应该更长?更短:说明大部分时候命中。CPU访问数据应该是有规律的——程序访问的局部性原理。

- 时间局部性:重复访问。
- 空间局限性:相邻存储位置,没有超过一个范围。

factorial:存在Cache里面 反复调用
score:我的数据和上一个同学的数据是相邻的

未命中时:返回给CPU的同时放给Cache。

把相邻的数据也传送回来,以防后面会被使用。块是事先定好的。所以所属块在Cache,字也在Cache。块不在,字也肯定不在。所以只需要对块进行标记。看块号在不在Cache中(就不用看字在不在了)。

分了两种情况:得到的结果中Tc:检查阶段的耗时 (1-p)Tm:把数据传给CPU的耗时
只有p可以改变。Tc也可以根据Cache来改变。
Ta<Tm:基本要求 Tc/Tm相对比较小
难点:容量小 命中率相应也会小 p实际中是很高的值

容量

是越大越好吗?带来的影响:
1、命中率会提高,成本会上升
2、主存是地址解析直接选中,不是找的,但Cache要找,寻找时间Tc会变长
3、大到一定程度命中率的上升会变缓,访问时间倒不一定

容量并不是不断上升
映射功能

同一个块,前面的一段相同,就后面几位不一样,前面相同的部分就可以作为块号
8个字节:后三位 16个字节:后四位 后log2:块内地址 前面的:块号

i=2 j=4 前三在第一行,最后一个在第二行不好 两种方式:12第一行34第二行 13第一行24第二行 mod说明是间隔放的 如果12在同一行,间隔时12 34可以连续访问,都在Cache里面,不会被顶替


标记位:直接放块号肯定可以 两个块映射到同一行:低的log2C位相同 如0和8的后三位都是000
看0号块在不在Cache,只需要看第0行 比较是0还是8还是16:只需要比前面的,因为后面肯定相同(标识行号)
所以n=log2M(块号的长度)-log2C(行数,不用存)
log2C反映映射的行号,Cache的行的大小和主存的块的大小是相同的,所以块的大小也是8个字,低三位为块内 地址 中间两位为两个行号,剩下两位区分不同的块

行比较小容易出现抖动现象:所以直接映射适合大容量Cache


灵活:允许放在任何位置,像停车场

判断行是不是某个块,必须知道完整块号,没有别的方法推断


要停在这一片,但这一片的具体位置可以随意 K:每组里面包含的行数 S是组数

红框是一个组

n不需要放块号,同一个组的log2S位是相同的


K=1:一个组里面就一行 相当于每个块映射到每一行是固定的
K=C:S=1,就一个组,跟关联映射没区别

关联度低,容易被替换,命中率低;可能的位置少,时间短;标记的开销小
替换算法

直接映射:每一个块只有一个可以摆放的行,所以只能替换那一个块
关联映射和组关联映射:需要选择操作 要把最最不可能使用的块替换出去


删掉最长时间没被用过的数据块。 1表示刚刚被用过,0没被用过

初始化:每个都为0 如何保证替换的为0的就是最早进来的:先进先出算法 会把下一行设为0 像击鼓传花一样
假设1:上一个被用过最有可能使用 修改 用一次设一次USE
假设2:上一个被载入更有可能使用 创建 被替换一次设一次USE

看被访问的频率,设置了计数器

因为能进入Cache频率本来就比较高了
写策略

看有没有被修改,如果有修改被替换时要写回

违背初衷:减少对主存的访问,而且没必要一直保持最新
如果多个CPU共用一块内存时,很有用处,因为数据可以一直最新

利用脏位来标识块有没有被修改
有时需要强行写入
行大小
容量定下来,行的大小该怎么调整?

行数会减少,替换会变得频繁,抖动会很严重;数据也离得比较远

如果是两级:L2容量更大,才能装L1没有的东西,L2从内存,L1从L2获得数据。
为什么要两级?只使用L2?
两种访问:1、按概率 2、按流程,这种更有利

可以帮助消除竞争
10 外部存储器
不在计算机系统内部

用于存数据量比较大的信息
非易失:不能断电就丢,要一直在那里
磁盘存储器

至少要表达两种稳定的状态
飞行高度:旋转时有磁头在磁盘上面,影响磁性物质,达到读和写的目的
希望存储信息比较多:每位信息占的面积要比较小 如果磁头离磁盘远:不太好辨识
飞行高度低:让每位信息所占面积变小 但要求平整(防止意外撞到)

看基材的材质是软的还是硬的:上面外观,下面是拆开后 片上有磁性物质
软盘:
上面的银是下面的黑,要放到软盘驱动器使用:直接塞(光驱要打开再放) 框和圆盘的框对上就可以读写数据
0.44M:很小
非常容易损坏 读一遍可能就坏了
机械硬盘:
- 原理相似,用磁头读取写入
- 更加稳定,不容易损坏,体积更大
- 可以多个盘片叠在一起
结构

蓝色框:中间轴 把盘片串起来
红色框:盘片 每个盘片上下两面都可以存储信息 所以右边有10个盘片
绿色框:读写头,吊杆可转,会移动到目标位置进行读写 (图里面是平移)

上下两面都要配磁头(红色小圈)
一种方式:所有磁头被连在一起(吊杆),同时移动
另一种方式:磁头不变 盘片动
答案:磁头和盘片都在动 磁头只沿着直径的方向 盘片不断地转动 就可以访问所有信息
轴和盘片是固定的,比较稳定

读写的时候改变磁性物质的朝向,所以磁头需要产生(写)/感应(读)大磁场
- 小——电磁感应能力弱 离盘片要近 更高的数据密度:每个信息更小 磁头也需要更小才能读出来
温彻斯特:保证离磁盘的高度比较小
读写机制

磁头静止:到达磁道需要磁头的移动,但这不在读写期间。到圈后才开始读写,此时磁头不动。
读和写有不同机制:用双磁头

线圈:改变电流方向,磁场方向也改变——磁盘上的记录介质也会变
不同的电流方向——不同的磁场——形成不同方向的排列,即写入
不加电流:经过物质也会产生感应电流,也可以通过感应电流方向的不一样读取信息

电阻会随着介质的磁化方向而改变,MR敏感期会根据电阻变化引起的电压变化看是0还是1
- 不需要电流的改变,只需要看电压的改变,速度会比较快(读比写快)
数据组织

扇区存的数据量相同,默认512B(要记住)
磁道的编号:从外往里(要记住)
不读数据,磁头一般停在磁道0

恒定角速度:利用圆盘的半径
可以得到恒定的数据传输率 不管看起来大还是小,数据量是一样的,时间又是一样的
比较好寻址
缺点:外侧要比较大,内侧要比较小 内侧能存外侧利用率就不高了 受到最内部的约束

外侧扇区数比较多,提高利用率
相同数据量:内侧圆心角大,转速要快;外侧圆心角小,转速要慢 转速不一样 所以需要更复杂的电路
问题:每个磁道的划分方式都不同吗?不是
磁头要做的很窄,假设信息分布均匀,从里往外,直径变换很小。
- 往外一层:100个,按跟刚才相同的划分,可以用和刚才相同的转速访问
- 往外多层:量变带动质变,可以放得下101个,转速也会变化

从上到下看

格式化:将磁盘组成上述方式。
ID域:校验码,防止出错
数据域:和ID域大致相同
同步字节:怎么知道是扇区——看扇号——怎么知道01串是扇号——特定01串同步字节
间隙:处理反应,用于判断下面的数据域是不是想要的(以免漏掉数据),转速越快间隙越大
格式化后还可以恢复:数据没有真正破坏掉,所以可以读出来
磁盘损坏了后数据恢复:无尘实验室打开硬盘盒,一个一个硬盘片拿出来放在好的磁头的地方读
(可能是磁头/盘片损坏)磁头撞上灰尘会损坏
低级格式化:完全清除里面的数据 不能分区(如分cd盘) 对硬盘有损伤 可以标识坏的数据
数据域变大更有优势:4096(4K)避免更多扇区的IDE 可以提高磁盘容量的10% 作业按照512
I/O访问时间

寻道时间:有时考虑跨越距离的多少,有时不考虑
旋转延迟:磁头到达磁道后,等待需要读取的扇区到达下方
- 等待时间为0:快到是最好的,读取同步字节发现是需要的扇区
- 等待时间为旋转一周的时间:同步字节刚刚过去
- 平均下来是旋转半周所需的时间
传送时间:b/N:传送的字节覆盖的距离 r:盘片旋转的速度 1/r:转一圈需要的时间
- b<N结论成立,b>N还要分情况讨论

平均时间:对寻道时间和旋转延迟取平均
实际时间:传送时间
每跨越一个磁道都考虑旋转延迟
从第一个到第二个通常不考虑寻道时间,因为距离短,所以只考虑到达第一个磁道的时间开销。
- 如果明确知道每一个相邻的寻道时间,需要加上去!!


- 到第一个磁道:4ms
- 1min:15000r 4ms:1r 平均旋转延迟:转0.5r 2ms
- 500扇区即一圈:4ms
- 后面不计寻道时间了

- 读一个扇区:旋转一圈的时间除以500,即4/500 比之前长了很多
磁盘整理功能:帮忙找一块连续的区域存进去,就可以是顺序组织,时间较短。
有助于碎片化存储文件:方便未来修改文件,留一点备用的空间
但也不用做很频繁:涉及文件读取到内存并读写进磁盘,负担大
磁头寻道/磁盘调度(6种)

决定哪个任务先做,哪个任务后做
- 所有任务已知
- 任务是逐步到达的

按照顺序被处理:把总共移动的磁道个数加起来,然后求平均 效率比较低

优先最近的,远的会被拖延:最外侧和最内侧很容易被忽略 饥饿现象

沿着一个方向走,走到边缘(TRACK_NUM磁道数!)调头 不存在饥饿现象
响应不均匀:位于中间响应频率高(等待时间平均一点)

到头后不扫描回来,直接到另一头从头扫描
响应频率平均

不走到头,没有请求就立刻改变方向
代价:SCAN->LOOK,190的任务没来,就立刻调头,要等18结束再回头,任务等待时间非常长

到头后会返回起点
光存储器

高清和蓝光的关系?
光存储器分为两面
CD CD-ROM

CD-ROM:更好纠错,更加稳定
母盘按后会形成对称结构,在凹凸不平面镀反射性强的材料 按->金属层->保护层
压从上往下压还是从下往上:**从上往下 **下面是聚碳酸酯塑料 按完后镀一层铝(黑色) 铝上是保护层:丙烯酸树脂
亮晶晶的一面:下面 保护层不透明,聚碳酸酯塑料透明 上面是标签(画)
激光读取:从下往上(虚线 朝上发射激光 朝下被反射)

磁盘和磁驱动器在一起,但光驱和光盘是分开的。
光驱发低强度光束,凹坑比较散,台比较强,就可以表示两种不同的状态。
光盘的数据组织:一个螺旋线从里到外连着,为了存储更多的信息。
扇区长度一样,速度一样,经过每一扇区的时间也一样。
两个扇区:内侧角速度大(因为长度相同,圆心角大) 转速则不一样,里面快外面慢 磁盘是角速度恒定的?
- 红色框:同步字节
- 黄色框:第几分、秒、扇、模式
- 数据
- 层次:辅助数据 和纠错码比较像

速度比较慢
CD-R CD-RW

解决了写和反复写的问题。
DVD

- 位更紧密:线间距变小,凹坑间距变小,容量相应到7倍左右,所以读取激光束会更细
- 所以DVD光驱能读CD,但反过来不行
- 双层结构:可以读取两层的信息,容量进一步增加
- 两面都可以记录数据
- R RW可以写和可以反复写

凹坑更小,数据可以放更多
磁带

磁头一开始停在最外面,可以直接到达目标位置,所以是直接读取。
长的带子,要把目标前面的带子滚完,所以是顺序读取。
串行:沿着蛇形方式 先扫磁带0、再磁带1 类比马路和洒水车
回顾:快闪存储器

U盘和固态硬盘

固态硬盘无磁头,对振动不敏感,半导体存储器,没有轴转动,没有机械磁头移动,所以有很多优势
- 已经出现非易失的内存了,可能会替代固态硬盘

11 冗余磁盘阵列

为什么需要RAID?
想着更多的硬盘合在一起会不会更好,增加容量
解决硬盘速度的问题,解决可靠性的问题
分类

0:解决条带化
1:镜像
2、3:并行存取
4、5、6:独立存取
RAID 0

存完条带0,存条带1(并不是存同一条带的条带4)
好处:数据传输变快,I/O请求响应变快
- 4个硬盘可以同时往外输出,往内写入,所以读写会快(针对大数据块)
- 小数据块可能位于不同磁盘上,两个I/O请求就可以不用依次响应,而可以同时响应(针对小数据块)

劣势:
- 出现错误的概率升高 有一个崩掉所有就崩掉
- 非冗余 坏了就坏了
RAID 1

冗余盘:简单地进行了拷贝 数据可用性增强(坏一个不要紧)坏:圆柱上所有条带不能访问
两个I/O请求即便位于同一个磁盘:
- 有备份 可以同时响应 所以响应速度比单盘快一倍
- 数据很大时读取也会快:0-4 0-7 可以白灰分一下下
- 写的话并不快,因为要把两个都写完 受限于白灰中更慢的一个

一半的磁盘存冗余,所以昂贵


先条带化、再备份:0坏了 12不可以联动 因为2只能和3配合 如果3再坏了 01就不能工作了
先备份、再条带化:不存在上述问题 同一组的磁盘谁坏了不要紧 12可以联动 所以10更好
(具体不是特别理解,感觉对条带化出错的过程理解不是很清楚???)
RAID 2(弃)

并行技术:不仅大数据块参与请求,而是所有磁盘参与每一个请求
条带:用满了才能用下一个 所以要很容易填满 所以条带非常小

奇偶校验码:不管前面多长生成1个 海明码:8个生成4个 4个生成3个
- 读数据,用校验码判断数据有没有问题
- 写数据:同时读写
1只能解决盘坏了,不解决数据出错:只发现数据不一致,不能确定哪个是对的
2可以解决纠错问题

数据本身已经有校验码,再加一个海明码意义小,反而影响读写效率(读要检查,写要写入)已经被弃用
RAID 3

少了校验盘:1个 奇偶校验码 好处是大大减少校验盘的数量
奇偶校验只能发现有错,不能判断,所以学海明码?
RAID冗余:防止磁盘坏了而不是纠错数据 坏了:明确定位哪里读不到了 出错:混迹其中 还是可读
怎么做数据重构?假设P(b)发生损坏 通过异或恢复
- 假设是偶校验 P(b)=b0异或b1..b3 两边同时加异或b1..b3 满足结合律和交换律 自己异或自己=0 右边只剩b0
- 假设是奇校验 P(b)=b0异或b1..b3异或1 两边同时加异或b1..b3异或1 所以奇校验多异或一个1

是让单个I/O变快,而不是面向多个请求
RAID 4(弃)

目的是解决多个I/O请求

更新每个块,还要更新校验位:要先读出来,然后再写进去(RAID3每次所有都要重新写,不存在这个问题)
校验位公式:先列P(b)=B0异或…B3 P(b)’=B0’异或B1…B3 两式异或得公式 (要读两个数P(B) B0出来)
较大I/O写操作:B0..B3都要更新 只需要利用新的数据算就好,一个都不读
写操作大问题:修改的两个数据块即使不在同一行和列,也要争夺校验盘,因为只有一个 所以被弃用
RAID 5

灰带:右上角到左下角:校验盘拆散,分布在每一列
优点:省 80%
缺点:只能坏一块盘(可用校验位算出来坏的位)超过一块就无法恢复
相比4的改进:块0块6同时修改:1354同时访问,不冲突(块6——P(4-7))
- 块0被修改,P(0-3)被修改占用,P(20-23)和P(0-3)在一起,P(0-3)影响块0/1/2/3/7/11/15 P(20-23) 块20/21/22 其实不完全独立,还是有很多制约(行列都有冲突) 但比4好很多了
“两读两写”:
先读B0 P(B)无所谓 可同时读或分开读
写也无所谓,但要在读后面
- 最好的情况:同时读B0 P(B) 同时写P(B)’ B0’ 2倍的时间
- 最坏的情况:完全不重合 (没考虑等待时间) 4倍的时间

每个里面坏一块可以,但同一个5不能坏两块以上
容量利用率会降低
RAID 6

同时3个故障出现故障才丢失:允许坏两个
但写每次影响2个,写效率降低
比较

0:同时利用多个磁盘
1:非常可靠 最低容量利用率:50%

2:容易坏 所以用海明码
3:很小的数据校验码(奇偶)1个 用于修复坏的

12 虚拟存储器
操作系统


用户和硬件之间
本身就是程序:需要占用计算机的资源,又会有效分配资源
存储器管理

- 除了操作系统,会放多个程序,为了让处理器不空闲:多道程序设计
- 多个任务都要被载入到主存

- 交换:处理不了就先放置,先处理其他任务
- 虚拟存储器涉及虚拟地址(考点)
分区方式
简单固定分区

- 长度不等,固定长:128、64都是固定死的 为什么不等:找容纳的可用的最小分区
- 一个区只能放一个任务 可用:没有被别的任务占
- 容纳:区的容量比任务的大小要大
- 浪费空间:
- 193KB只能放在256KB
- 1KB 前面的都不能用 只能放在384KB
- 2个100KB 一个占256KB 一个占384KB
可变长分区
系统区固定,变的是用户区
3个分散的空,不能被利用:碎片 时间变长会越来越多
- 能不能拼起来?重定位,额外开销….有没有更好的方式?
怕碎片,就把它全都变成碎片
分页方式

- 页装进页框:同一个任务中的页不需要在连续页框中存储,可以跳
- 任务5分成3个页 1718被占用 接着放第3个页在19的位置
- 麻烦:主存块的真实位置不连续,压根不知道这些块怎么分布
- 引入逻辑地址、物理地址,需要来回转化,知道对应关系页表 每一个进程都有相应的页表
- 逻辑地址:所有地址都是连续的
- 物理地址:实际的地址,根据每次语句载入而变化

- 请求分页:对于每个任务,只把当前要用的载进来
- 把逻辑地址转成物理地址
- 可能不在主存里,因为只放了一部分,可能未命中
- 每次只载用当时用到的页面,如游戏可以写很大,同一时刻用到页面有限 游戏可以大于物理空间,只要保证同时载入的页面是可以被物理空间接收的——丰富了程序

- 把所有的页载入到硬盘
- 当前任务正在使用的页放到主存(真正载入) 页表:记录每个页的状态(在不在主存里,有没有被修改…)
- 主存和硬盘会有的交互,可能还会往回写

Cache里访问主存代价比主存没有访问硬盘代价小
尽可能避免对硬盘的访问,提高主存的命中率
提高命中率:页大小大很多,一次性可以搬更多,减少交换次数
- cache容量小,放大了会挤压别的空间;页空间大很多,后者过一段时间去用,减少对主存的访问
- 全相联映射:命中率最高
写回:肯定不能玩一下写一下硬盘 非常卡, 载出去的话再写一下
分页式虚拟存储器

- 页表:所有虚拟页状态信息
- 肯定不存在硬盘,否则每次都访问太慢了,要放在主存
- 有一个连续的很大的虚拟存储空间
- 写程序启动后,会产生很多页面,需要很大空间
- 没有那么大空间,所以载到硬盘
- 把要用的搬到主存,在什么位置呢?页表来记录(存在主存)

- null:没有存任何东西
- PP0,PP1:里面有页面,已经存在了主存中 最长:某个页的物理地址(即物理页框号)取出来合并就是页内偏移量
- 空:有对应的虚页,已经有内容存在硬盘上,用指针形式表示位置 比较短
1、存放位置长度是统一的:
并不是按照实际的长度 按照PP0物理页面地址的长度 因为虚页会变化 存放位置三种情况都有可能
2、每一行需不需要记录虚拟页号?如VP0、VP1:不要
所有虚页都放进去了,程序运行过程中不会再多一个虚页了,每一个页的顺序是固定的
3、虚拟地址和物理地址的转化:利用页表
页内偏移量相同,只需要用物理地址替换虚拟地址
虚拟地址和物理地址哪个更长?虚拟地址比物理地址更长:不用一下子载入,可以写很长
虚拟页号也会更长一些:虚拟页号=虚拟地址长度-页内偏移量 物理页号同理

每次知道页面都要查页表
使用Cache:减少对主存的访问
使用虚拟存储器:能不能少访问主存:页表放Cache 整个太大了放最活跃的几个

VA:虚拟地址 PA:物理地址 valid(装入位):这个页已经从硬盘载入主存了

1、CPU要取数据,发出虚拟地址,首先需要转化成物理地址,否则不可能抓到数据(主存只有物理地址,从页表到硬盘太慢了)

2、先查TLB。
- 一种正好命中且已装入:问题:可能invalid吗?没有,为什么?因为装入了才可能命中?

- 未命中:去页表查,因为保留所有信息,肯定能查到:
- 已经被载入主存了,可以被替换成物理地址
- 没有被载入到内存:发起缺页操作,从硬盘到主存

3、现在就有PA了,来看Cache。TLB也可以看做Cache。
- 命中,cache把数据给CPU;

- 未命中:根据物理地址去主存中取相应数据,块到Cache,字节到CPU

- 缺页:页不在主存:把页从硬盘到主存,再从主存到CPU

- 红色:虚拟地址到物理地址的转化
- 蓝色:缺页操作。主存中有没有空的地方,没有时需要替换:用新的替换旧的 更新页表和TLB(可以保证都在主存里 前面不可能有invalid)
- 绿色:cache操作一模一样

2 cache那里要访问主存 3 访问主存的页表 4 cache和TLB两次 5缺页,需要访问硬盘
67 TLB留下记录的,页面肯定载入主存了 8 主存没有cache里不可能有
缺失后怎么处理?Cache:硬件 页表:软件 TLB:硬件或软件
分段式虚拟存储器

页的划分不知道,段的划分程序员知道:一块一块,长度不固定,会引起碎片
段页式虚拟存储器

页号+页内偏移量:相当于段偏移量 物理页号是页框号!不是实际地址

13 总线

简化互连的复杂度

每个房子连在路上,路也分层级(多层结构)

类型

分为芯片内部总线、系统总线和通信总线。主要讲系统总线。

Intel:特指I/O bridge和CPU,但前面说的还包括所有绿色框里面的线。

数据线根数:决定可以传递数据的大小 因为一根线只能传递一位数据
地址线:指定从哪来到哪去 根数多,地址长度越长,地址所含位数越多,寻址空间越大
- 16:不可能大于2^16
两个计算机系统地址线相同,寻址空间是否相同?差不多
- 特例:地址是64位,可以分两次把地址传(先行地址再列地址),此时寻址空间可以得到扩展

控制线:防止冲突 I/O还有中断
时钟:同步两个设备协同操作

听可以一起听,但只有一个设备发送数据
使用时不可以抢夺使用权,无论优先权有多高
设计要素

用途

- 专用:功能单一,服务对象单一 不需要和其他设备分享,想传就传,冲突率小吞吐量大 成本高规模大
- 复用:节省空间成本 但要控制冲突、复杂性增加
仲裁
要决定哪个设备使用总线:

优先级和公平性两个是矛盾的

- 集中式:辅导员分配
- 分布式:自己商量
集中式
链式查询

请求信号:一个或多个设备想使用总线
先判断是否使用总线(看有无请求信号):
- 使用就把允许信号//截下来,不使用就继续传下去(传递需要总线不忙)
繁忙:是双向的。当总线忙,不允许被使用。
- 发允许信号要求总线不忙
- 发起了请求,也拿到了使用权:要把总线设为忙
- 想使用总线:先看总线忙不忙,如果忙就不发送请求
总结
绿色线串联起设备,每个设备先监听总线忙不忙,不忙就发起请求(同一个周期里可能有多个)。
蓝线拿到请求会先看总线忙不忙,如果不忙就会在绿色的线上发起信号,每个设备会依次拿到允许信号,根据自己发送请求与否决定是否传下去。想使用:设为忙,不往下传;不想使用:继续往下传。
- 优先级是严格固定的,公平性比较差

对电路故障敏感:根据自己的状态决定传不传下去,无法判断是设备坏了还是想使用。一个坏了,后面的所有都无法使用总线了
等待时间长,响应速度慢:平均n/2
计数器查询

- 允许线换成设备ID线:报号 如果想用就发送请求
- log2N根线同时监听,才能知道报数是不是到自己(才能表示N个地址)
区别:辅导员说而不是同学说了 窍门:报数可以改变顺序 1234 3124

某个设备坏了影响不是很大
需要知道喊的是我:需要解码和比较ID设备的硬件模块,速度也相应变慢
独立请求

非常灵活,优先级和公平性都可以通过不同策略有
想用就可以请求,不需要等,速度得到大幅提高

分布式
自举式

只关心比我优先级高的设备用不用:公平性受影响
设备3优先级最高:不用管别人 只用自己发送请求
向下:关心其他设备要不要使用
向上:发送请求
BR3:设备3想用总线,设为1,设备012会接收到信号。
设备0没有表达请求的线:只用看BR0繁忙上有没有信号,不忙就可以申请
总结
首先看总线忙不忙,然后表达自己的请求,同时看高优先级的有没有请求,如果能用就把总线设为忙。
冲突检测

看到椅子没人,就立即去坐。感觉到挤说明有冲突。都站起来。各自随机回退一定距离,再重新抢。
很公平,但没有优先级,需要时间,效率相对低
时序

异步:前后事件的衔接
同步时序

约定好策略
- 快的迁就慢的(一个时钟周期准备好)没办法发挥高性能优势
- 如果想同步意味着总线不能太长
异步时序

伸一只手,再伸一只:有先后关系 三个不同的状态
- Ready:准备好了可以来拿 上升沿:准备好 下降沿:撤了,为下一次传输腾空间
- Ack:拿完了,通知一声拿了 上升沿:取好了==可以把ready信号撤了 下降沿:撤掉“取好了”
非互锁
先“准备好”,再“取到”:没有额外限制,必然状态
半互锁
知道“取到了”再撤掉:防止ready信号撤早了 如果撤早了ack可能压根不知道ready准备好,会一直等
全互锁
知道“ready撤”再撤ack:防止ready不知道ack取好了,ready就会一直等

全局:CPU有某个地址,从存储器取数据后传给CPU 3次握手完成地址传输 3次握手完成数据传输
两个Ready信号:
- ReadReq:地址就绪
- DataRdy:数据就绪
Data:地址线和数据线复用(用的同一批线)
1、先设置地址才能读
2、存储器读完了,CPU请求和地址才能被释放 否则存储器不知道读请求
3、“读完了”信号才能被释放 否则CPU可能不知道读完了,会一直放着数据线
4、承上启下,开启对数据的传输
5、读数据
6、知道“CPU读完了” 存储器才能释放请求和数据 否则CPU不知道读请求
7、“读完了”信号才能被释放 否则存储器可能不知道读完了,会一直放着数据线

所有事情的发生通过信号:对噪声敏感
半同步时序

异步很随意,所以容易被噪音影响。
限定时间点:某个时钟周期的节点:使得和噪声混淆概率降低,比如要求在时钟上升沿
分离事务

把一个总线事务分成两个:中途可以让别的设备使用 提高总线利用率 但一个事件的时间增加
总线带宽和数据传输率

总线带宽:与时间和数据量相关,时,数据传输速率**比较现实。
地址总线:可能多次传输,但地址总线越宽,一次传输的地址位数越多

同步:CPU发地址给内存,内存准备数据后将数据传输给CPU
读一个32位的字:总线正好是32位宽 所以只需传一次 一个时钟周期就行
总共传了32位:数据量/总耗时

1、CPU把地址传给内存
234都可以准备数据,因为不需要数据,5:取234和数据准备的最大值(按图片左边的来,右边指下一步!!)

同步:250?一个时钟周期只能做一件事 确定了开始和结束的时间 230/50 = 5 5*50=250
注意下面这道题是同步(3步)。异步则有7步。

每次传输:靠一个地址来传输 表示一个总线事务传4个字或16个字
因为能整除:传256个字、4个字、16个字数据传输率一样。所以只需求每次总线事务里面的就可以了
传输时间:总线事务传输的时间*总线事务的个数
每秒总线事务数:1s/总线事务传输的时间
2、64位宽:每次传2个字
3、2个空闲的时钟周期:算到总的时间开销
4、cache的原理:前四个字未命中,后四个字命中

过程依然是CPU发地址给内存,内存准备好数据后把数据给CPU
一个地址:一个时钟周期
数据准备:只准备前4个字所以需要200ns
一个时钟周期:2个字 所以传输4个字需要两个时钟周期
总共需要256个字,需要这样的操作64次
200MHz:1s有(200 * 10^6)个时钟周期,所以一个时钟周期的时间为 10^9/(200*10^6)=5ns
这个传输时间有64个总线事务,所以一个总线事务:14400ns/64 每秒的总线事务数就是用1/(14400ns/64)
数据传输率:256个字,每个字32bit

16个字:准备4次 前面的数据在总线上传输时可以准备后面的字
第一个传输与第二个准备叠,第二个传输与第三个准备叠,第三个传输与第四个准备叠,20ns是四个时钟周期,所以取大的。数据准备好了连续传是可以的,不影响这里的结果。
蓝色的2:最后的4个字传输的时间
黑色的2:表示空闲

提高频率:缩短周期
数据线根数变多 时间不变数据变多(分子变大)
一次传一次地址,可以穿一大块地址:同样的数据量,减少了地址传输的时间和数据准备的时间 但需要额外的支持
释放总线后:总线可以传输别的 空闲时间干一些其他事情 可传输的数据变多 每个事务的时间会变长(要等车)
写操作可以同时传过去,不需要等待先传地址再传数据
总线层次结构
单总线结构

长度增长,延迟变大,协调困难
请求多,总线成为瓶颈 车多路窄
双总线结构I

CPU需要指令和数据
CPU如果还要和I/O模块谦让效率就会降低
还可以分流系统总线
双总线结构II

IOP:输入输出处理机
原来的总线改名成存储器总线 可以减少I/O对总线的影响
多总线结构I

- 加了cache,本地总线
- 这时候cache还在cpu外部,现在在内部了
多总线结构II

主存没有连在系统总线,而是高速I/O
DMA:其实是通过CPU在进行交互??
多总线结构III

分了低速和高速
14-指令系统

计算机:处理器执行指令来完成
指令集:能执行的指令的集合 不同计算机有不同的指令集



如何解析01串?
解读方式:依据指令格式:分成几段 一般不止一种格式 所以避免二义性
0/1串给人读很累:符号表示法 操作码写作助记符 操作数用存放的地方来表示
操作码




移位怎么做?
- 逻辑:空出来的位置补0
- 算术:符号位不动 左移补0右移补符号位
- 循环


指令寻址

- 实现循环和条件判定

- 不同:包含隐地址 接下来一条会被跳过去,或者是下一指令地址
- 更加灵活

调用怎么实现?关键是返回的那个点在哪里,只要把返回指令的位置记住就可以调用了。
4100有调用过程1 返回地点:4601 4651 4101
RN存下一条指令(PC+三角)的地址,把需要调用的首地址X放到当前寄存器PC 执行完以后再从相应寄存器中取出地址
问题:过程1再调用过程2就不行了,需要无穷尽的寄存器 所以这个方法只支持无嵌套的调用
怎么去做多层调用?黄色框
- X:被调用过程开始的地方 返回的地址放到了被调用的函数开始的地方,然后从第二条开始执行
- 所以被调用的方法:第一条是空出来的:存放调用他的需要返回的地址 第二条才是指令开始的地方
- 4101:放在4500的位置 4601放在4800 4651放在4800 最后返回到4101
- 为什么需要使用栈:前提:返回的地址不会在过程执行中被修改 什么时候会被修改:执行时有人调用它,意味着自己调用自己(递归解决不了) 然后会覆盖原来存下来的地址
使用栈:解决递归
- 返回的地址压入栈
操作数

- 提供四个地址引用,但下一指令地址一般是隐含的 目的操作数:结果操作数
- 可以把源操作数当做目的操作数(只需要两个,图2) 有一个默认的位置(AC寄存器,只需要告诉第二个位置)(只需要一个,图3)所以地址引用的数量是不定的
- 地址数量越少,指令越短,不需要复杂的CPU
- 坏处:不灵活 约束比较多(需要规定某个操作数的地方)条数会变多,时间会变长(看三张图即可知道)
- 如果用多个地址,需要多个寄存器




大端:把低位数据放在大的地址
小端:把低位数据放在小的地址

字节层面反过来,而不是87654321,不影响字节内部的排列
大端:顺着下来的
小端:从32位地址直接取低位也很方便
操作数寻址



EA:指向的可能是操作数地址
(X):括号表示里面的内容
立即寻址

实际出现:不是直接寻址是立即寻址!!立刻通过指令本身获得操作数,什么都不用干 只需要取一条指令
数据的长度受限于地址字段的长度,表示的数的大小有限
直接寻址

可以获得操作数的有效(实际)地址,只要去存储器访问就行了
- 限制:有效地址的大小:因为是指令里面的一段
操作数永远可以表示成(EA) 这里就可以表示为(A)
间接寻址

指向的是存操作数的地址(有效地址的地址)
- 缺点:要访问2次存储器
- 好处:扩展地址空间
解释:虽然多了一道寻址,但A还是有一定约束,不过这不一定是坏事
寄存器寻址

缺点:寄存器少(精贵),需要很好地利用
有效利用:把一个数据从主存放到寄存器,读了再算,再放回寄存器没有意义
如果多次访问寄存器才有意义,否则是对寄存器的浪费性的使用
寄存器间接寻址

第一步用的寄存器的地址,比间接寻址少一次存储器访问,但比寄存器寻址多一次存储器访问
偏移寻址

需要算:寄存器的内容+相对偏移
哪个是显式的?A

局部性:差不会很大,可以节约地址的位数 用相对短的差替代比较长的地址

会给B:重定位怎么确定真实地址?相对基础地址来定义,看偏移量即可

前面两种变化的都是A,跟数组下标很像。A是数组第一个元素的位置,R表示下标,用自增的寄存器可以对数组进行遍历。
两种变址结果是一样的。

指针指向栈顶,保存在某个寄存器。知道栈顶的位置,再用偏移量取对应数据出来
- 与零地址的关系:可不可以不要地址?表示操作数存在固定的地方 两个操作数按照预设的顺序存在固定的地方——栈
栈寻址

后进先出

分隔开:栈顶针存放着当前的栈顶,即可进行操作
- 栈基放低地址:向上增长
- 栈基放高地址:向下增长

后缀表示法更好:不需要括号,很容易利用栈来进行求值运算
怎么把中缀表达式变成后缀表达式?中间:从左往右扫描 遇到操作数:输出 遇到操作符:压栈,如果优先级高:压入,如果优先级低或一样:不断弹出知道遇到优先级更低的(相等不行)(+X 遇到+ 弹出X和+) 遇到左括号压 遇到右括号:弹出操作符直到遇到左括号 输入为空再把栈里的依次弹出
后缀变成中缀:是操作数:压进去 是操作符:运算后把结果再压入
- a b c ->a bc-> a+(b * c) -> a+(b * c) d e -> a+(b * c) d+e ->a+(b * c) + f(d+e)
指令格式


不是任意的,有这样的规则:
- 不能太短或太长
- 唯一的含义
- 字段的个数多了比较灵活,小了会短但是条数增加

短:节省空间
长:位数更多,方便
等于存储器的传送长度:可以正好取一条指令 不要少一块或者多一块

涉及操作码和操作数怎么分配:
操作数长寻址能力强,操作码长可以更加灵活
- 变长:可以占用更长的区域 前提是操作数需要的位数少/需要的寻址能力少
- 字节寻址比较细,需要更长的地址;16、32位需要更少的地址位

- 优点:提供比较多的操作码
- 怎么保证可以取出来这些指令?按最长的来

- 完备性:也不是越多越好
- 兼容性:原来的软件也能用
- 多种数据类型都能进行处理
- 可扩充:为新增的操作码提供可能

操作码为什么那么多:指令条数不要太长,操作码类型也不要太多

15 指令周期和指令流水线
指令周期


- 解析操作码->看操作数(计算EA有效地址,取操作数,多次往复)->操作数据(运算)->算结果放哪里->取下一条指令(算地址) 中间:返回字符串或数据还需要再译码

加了中断:检查有没有中断。
做完一个案件不是立即取下一个指令:
- 中断禁止:回过去取下一条指令
- 中断允许:检查有无中断及处理中断

有中断朝右(处理完了也会朝左),没时间朝左

间接寻址:需要更多的存储器访问 这里把读取存储器的过程当做另外的指令周期 因为涉及存储器的访问,所以单独拎出来(左侧是正常的指令周期)

取操作数:多了两个指向自己的。相当于取了两次。
- 提出的意义:相当于取了两次操作数,多了一些操作,反映在CPU中影响数据流和指令流水线。
CPU的任务

从数据流的视角观察

取指周期

1、指令存储的地址:PC 放地址总线上,因为不是直接连,先放在MAR再放在地址总线。
控制线要告诉存储器地址准备好了,存储器从控制线上获得响应信息。
黄色:存储器接收到准备好的信号后从地址总线读取地址,随即进行数据准备。

2、指令取好后存储器把数据放到数据总线。因为MBR与数据总线连在一起,再送到IR。
如果是同步,按时做操作就行。如果是异步:要反馈,绿色箭头含义是存储器已经准备好了。
一般都是同步的,所以画单向箭头也没事。

3、控制器会让PC+1。发生在指令取完后。

间址周期

- 要把间接地址换成有效地址:MBR里面获得的是间接地址,需要传给MAR,MAR再放到地址总线(因为只有MAR连接着地址总线),控制器会发送响应信号,存储器随之从地址总线上取地址。(区别在不是从PC开始而是从MBR、MAR开始了)

- 准备数据:通过右边的箭头返回到数据总线,再反馈到MBR。取出来的是有效地址(在存储器中转换)
- MBR可以一直认为连在数据总线上,数据总线有啥他就有啥
- MAR可以认为一直连在地址总线上
- 取出来的是什么东西?取出的是有效地址。取操作数在执行里做(和取指周期一样,这里返回的是有效地址)。
中断周期

多了一个PC
所有的东西都指向存储器:这里是写操作(刚刚是读操作)
PC到MBR:对PC内容的保存,处理中断要知道能返回到哪里
控制器通知PC,PC把下一条指令的地址放到MBR,MBR放到数据总线上

MAR放什么地址:保存PC寄存器中的下一条指令的位置的地址。存在存储器的哪里?由控制器告诉。类似栈里面调用的过程。中断也有这种过程调用。

控制器需要通知存储器:绿色箭头,知道要写入数据了
存储器会从地址线获取地址(红色),从数据线上获取数据(黄色),然后写起来(存的是PC+1)
指令流水线

流水线:把若干个阶段分好工 每一个人都只做了一部分事情
好处:每个人的步骤单一,熟练度得到提高,更快 CPU本来就是各个部件,非常适用。CPU就相当于生产线,各部件相当于装水的工人。
- 有一个工作最闲:贴标签 如果工作量分配不平衡就不好,会造成资源的浪费


问题:执行指令的时间长,都需要访问内存:访问冲突
取指令会经常等执行指令,但执行时如分支语句地址也需要等,会给新的地址,原来的会作废。

把执行指令划分成了5个组成部分。处理了时间不平衡的问题。

指令1译码时,可以取第二条指令…因为每个步骤由不同部件在完成
大大缩减时间单位

Load不需要写回操作数,需不需要简化呢?不需要,因为会多一条生产线,不执行空着就行(硬件设计便利)
不是所有并行:因为有冲突
时间难免会有差别:时刻的设计——以每个阶段中最长的,保证所有人都能做完

跳转:取回的指令执行不下去了,可能要取新的——代价大,做了一半的指令被浪费了(最后才知道跳到哪个地址)4567均失效(这里明显指令3是跳转指令)

跳转和中断都会发生浪费

红色框无效(因为I3是跳转指令,WO写入会把指令送到流水线执行,因为设定是在流水线上刚一出现就撤销)。绿色是空区域,把不该执行的指令的控制信号清零。
性能

如何评价这个流水线好不好:
ti:处理时间
tm:最大的延迟
k:多少段
d:上一阶段到下一阶段需要的时间 装好水后还要给下一个人需要时间(可能中间会放在桌子) 指令也可能放在寄存器,再从寄存器取出来,会有延迟
- 周期时间:最慢的ti+d

第一条指令:k个t,后面的每一条:比原来多1个时间阶段
kt+t+t(n-1个t)=[k+(n-1)]t
- 加速比:评价性能好坏:没使用流水线的时间/使用流水线的时间 大于1
理想情况下的公式
但需要考虑流水线失效:分母可能会变(跳转的话分母会变化)

阶段数越多,指令数越大,执行速度越快 但这不是绝对的,因为d会越来越多(延迟),不同部件使用相同资源产生的冲突也始终没有解决

冒险

数据依赖性:需要前面的数据算出来,而不是可以直接并行去做
控制冒险:有跳转或者其他的
结构冒险

不同指令同一时刻访问相同的资源:都要访问内存/寄存器
- 分成不同的存储器:指令和数据 而且引入了Cache 数据cache和代码cache是分离的,可以避免冲突发生
- 上升沿下降沿交给不同的使用:往里写,往外读,是不同的在使用
数据冒险

第一个指令 r1是结果 执行完才能得到 只有异或采用的新的r1,前面都有问题

nop慢慢等就行 坏处:啥都做不了

硬件插入气泡:硬件阻塞 比较复杂:要判断哪些相关,怎么做到阻塞 其实还是有时间开销

其实不是最后才产生r1:第三步就算好r1了(旁路,提前打听好)转发r1给r2,正好也赶得上r2计算(ALU前面输入)
什么时候有效?前面算出来的是可以用,有一种情况不是算出来的——load是取出来的,在DM后面才能拿到

两个lw:b到2,c到3 通过调整顺序让几条指令间不需要等
控制冒险


问题:取错了需要的,如果没取错就没问题:解决——不去选择,都取
当然也要控制数量:用一个循环缓冲器:在里面就不放,不在里面就取

另外一种思路:不多取,而是猜谁更对点(预测可能的分支)
- 静态预测:和现在的状态无关 预测规则不变(不根据处理的历史发生改变)
- 动态预测:

静态:来一个操作码就预测
动态:状态不同预测不同 对for循环

看是不是第一次:第一次就加,不是第一次看之前是怎样的,再根据这次的结果调整应该做怎样的预测

16 控制器

左边是ALU,然后是几组寄存器,下面是控制线,由CPU内部总线连接。CPU和内存:系统总线,内部是内部总线。灰色粗点的:控制通路,传递控制信号。
ALU里面的双向箭头:可能生成或者取
寄存器

- 帮助减少对主存的访问
- 控制CPU,大多数不可见
- 两者其实没有明确界限,PC寄存器在x86是用户可见,可以修改使用,不少机器上不能使用
- 有些明明是操作系统控制的,也是用户可见的
用户可见寄存器

- 通用:什么都能做,但也没有那么通用,如只用于浮点数或者栈操作
- 数据/地址:
- 条件码寄存器/标志寄存器:部分用户可见,如程序员可观察到 正负0溢出等存在reg里 可能不能被程序员修改,但可以通过一定方式隐含的被读出来 虽然是用户可见,同时构成控制寄存器的组成部分
- 条件码寄存器不一定是必须的,有优缺点:指令变简单,硬件复杂性,额外的操作

- 完全通用vs固定用途
- AC寄存器:操作数和结果可能放在特定寄存器 长度短 但不灵活 不仅涉及用途还涉及指令集
- 寄存器数量:少:不够用 多:成本上升
- 长度:越长越贵 可以保存大多数类型的值 两个:特定的应用

新的子程序,原来的状态也要保存下来 调用和保存:CPU完成,可以独立使用
- 子程序调用之外要保存:程序员的责任

- 取出来指令,PC就完成+1.转移跳转也会完成变化。始终指向下一条要执行的指令
- IR
- MAR
- MBR:包含写进或读出来的字,用户可见寄存器再和MBR进行数据交换
- CPU给ALU处理素材和结果,可用在CPU和存储器的交互



定制寄存器的设计,权衡寄存器和存储器

微操作

程序的执行分解为指令周期

左边就是一个个微操作
- MAR和地址总线相连 取地址是把pc的地址给主存,需要把pc地址放到地址总线上,pc做不了只能拷贝到MAR,而MAR和地址总线直接相连,所以内容相同 括号指里面的内容
- 主存会把要取的指令准备好,放到数据总线上,而MBR与数据总线相连,存储指令的值
- PC不一样:PC+1
- 指令放到IR寄存器 即把MBR内容放到IR寄存器
还没有写完:t1 t2 t3 会假设有一个时钟,每一个操作所需时间等长 微操作还要标识在哪个时间单位里
微操作唯一吗?不一定(当然一个周期里面调换顺序不算)
IR<-(MBR)可以放在第四个吗?不可以,时间要少

- 前后顺序要恰当
- 避免冲突:先读后写和先写后读不可能放在一个里面
- 满足条件下,时间尽可能少

- 指令中的地址部分:间接地址放到MAR 然后主存会读出(MAR)的内容,获得有效地址放到MBR
- MBR在t2是写,在t3是读,显然需要三个周期

- 根据IR寄存器的地址放到MAR,在从主存中取数据放到MBR,因为是间接寻址所以是(MBR)+(R1)
- 不能压时间:送地址才能写内容 t2写t3读
- 保存当前地址并跳转到另一个地方:1、把PC内容写到指定的地方,2、根据指令地址跳转新的地方
- MAR存了指令里的地址 因为要告诉MAR存到哪里 要跳转的地方在哪里 可能帮助传输给PC?
- PC放到MBR才能放到主存,且更新PC要跳转的地址

看看有没有允许的中断发生
- PC的内容放到MBR 存放地址放到MAR 新的地址放到PC MBR的内容放主存(备份旧地址)
- 尽可能少:2个就可以完成

怎么把各个微操作连起来?ICC表示四个不同状态

- 00:判断是不是间接寻址,不是就直接执行

01:读有效地址 就可以执行了

首先看操作码 对应不同的微操作序列 00:进入下一个取址

通过ICC把各个操作联系起来了

让寄存器和内部总线之间来回传递 箭头是数据流动方向
- MAR连地址线,把主存里的内容放MBR
- MBR绿色箭头指的和AC红色箭头指的可以同时合并吗?放进去并不会分别到ALU的两条线上,而是在总线上混淆,所以先放其中一个,用Y暂存一个操作数 这样看图可以进入ALU的两个分支
- 绿色箭头断掉AC才能打开,然后自动生成结果
- 结果不能自动返回到系统总线上,因为AC还在,会造成循环运算->蓝色暂存
- 第五步把蓝色输出门打开,红色输入门打开,就可以算出来了
控制器

- 定序:排列微操作 然后保证执行

- 指令中的寻址方式(间址周期) 操作码(执行周期)影响控制
- 标志:上一次的结果
- 时钟:标识时间
- 收到来自控制总线的控制信号:中断等

- CPU内的控制信号
- 寄存器之间数据传送
- 启动ALU功能
- 指向控制总线的控制信号(CPU外)
- 到存储器
- 到I/O模块
- 所有控制信号到最后是0/1作用到各个逻辑门 0关上 1打开

- 红色:PC->MAR C2打开(需要控制信号连C2 1) C0看成一直开着的(可到达地址总线)
- 绿色:还需要Cr(对外的读信号)告诉存储器需要读,然后放到数据总线上 打开C5就存入了MBR
- MBR->IR:出的 把C4打开连到IR,别的门都断了

- C8是到MAR的
- Cr/C5到MBR
- C4送到IR
中断:
- PC到MBR:C1
- MBR内容要写到主存,C12开,同时要Cw写信号

高频使用:只做最少的事情 只需要知道性质并产生相应信号 不用具体
实现

- 输入转输出
- 逻辑由微程序中的微指令控制
硬布线实现

4种输入:时钟、标志、控制总线信号、指令寄存器
标志、控制总线信号:都是0、1 溢出、中断请求等:都有特殊含义
指令寄存器有寻址方式和操作码
- 把操作码转化成逻辑输入:本来是编码好的01串(0001表示什么,0010表示什么)2^n种方式 但不方便
- 译码:n位 生成2^n种输出 某个操作码有特定位为1 实际困难一点
输入I1-4,对应了一个O的输出
- 0000 O16为1,其他为0
- 0001 O15为1,其他为0
- 这里需要log2(16)=4位来标识16位 标志

规范哪个时间单位,还是要转化为逻辑信号01
- 定时器分解为很多逻辑信号,在哪个阶段相应线为1,其他为0
- 时钟一直累加还是在一个指令周期内?一个指令周期内 T1 T2是子周期内部 完成子周期时钟信号会清零 t1+t2..+所需要的阶段 完成子周期(如取指周期结束)就清零

P/Q:表示在哪个子周期里 帮忙规定在指令周期的哪个阶段
C5:00的T2+01的T2 +或 两种情况值为1
执行周期有时候要读入操作数10:LDA:LOAD 为1 会更完整
所有的控制信号C都可以用布尔表达式表达->实现硬件
这样输入就可以变成输出的控制信号
局限性:布尔表达式数量非常大,超级复杂
微程序实现

固件:微指令:一行来描述微操作
每一个操作对应门的开关,要产生01控制信号 把每个线排好形成01串 就是一行

每个字标地址,来回跳来跳去,就可以不断输出控制信号
微指令地址:存跳到的微指令

任意一条指令,取指、间址、中断,微操作序列一样 微指令序列也一样
不同:执行 和操作数无关 和操作码有关:对应不同微指令 相同操作码->相同微指令
执行:拿出来01串放到控制线上发出去
红字:间:到黄 执行:到绿
黄:到绿
绿:分析操作码 跳到相应紫 最后统一紫(中断) 有:黄下到蓝 再跳到取指
任务

大小 时间:不想太慢
执行:复制01串到线上就行

双:二选一
单:一个地址 普遍
可变格式:12都有可能

定序逻辑:决定下一条地址,发送给控制地址寄存器,也会发读命令给控制存储器
控制地址寄存器:存下一个地址
控制存储器:根据地址读相应的微指令,放在缓冲里

黄色内容生成控制信号,绿色传(因为和控制线相连),蓝色决定下一条的信息,玫红传新的地址

- 生成新地址
- 顺序:定序逻辑中+1
- 跳转:新的放定序逻辑,再装到控制地址寄存器
- 机器指令例程
- 红色:01正好对应?但不够紧凑 实际可以编码(留下需要用的) 长度缩短
- 绿色:因为被编码了也需要译码器


17 输入输出

不是计算机系统,不是I/O模块。

数据交换:屏幕、电影 都是二进制输出 鼠标点击、麦克风、喇叭:二进制输入
内部0/1和外部环境的交互:通过外围设备 外设

不可以

- 鼠标、显示器、打印机大不相同 总线不能支持这么多的操作
- 大部分数据传送速度比较慢,少部分非常快 慢:等待 浪费 快:涌入大量数据来不及处理
- 数据格式可能不一样
I/O模块

把难以对接的两方面连在一起,外设非常多
I/O模块属于计算机系统,外设不属于 输入输出就是这里的I/O模块
上面连系统总线,下面连外设
- 上面:控制线控制信号 听令于CPU 地址数据线各自传 I/O模块有不同寻址方式 数据从内部到外从外设到内存都有
- 下面:

以统一的方式还是不同的方式:统一,因为外设层出不穷 分开太复杂了
- 控制信号:外设也受计算机系统操控 控制信号从计算机内部经过I/O模块输出
- 状态信号:由外设送里面:打印机没墨、卡纸,输送状态
- 数据信息:双向 有输出也有输入
背景色:抽象的外部设备
控制逻辑:用来控制外设的操作,控制信号它接收,状态信号它汇报,朝右箭头:控制的能力
大一点的框:
- 缓冲器 对接和I/O模块的数据交换 解决数据交换速度不一等问题
- 转换器:音频信号和01信号有区别,没办法直接输入输出,需要转换 喇叭有耳机,01要被听到,转化成音频信号 把设备特有的形态和01进行转换

I/O模块受到计算机系统的命令、数据、报告状态、分辨外设的唯一地址,也要能和外设进行交互。

速度不匹配,需要在两者之间做缓冲
每次同时处理三个人,一下子来了30人,人少也可以攒,都是缓冲

并不知道什么时候敲键盘,所以要做控制和定时


逆时针方向90°旋转
- 红色:连到了计算机系统内部
- 数据线连数据寄存器:
- 状态/控制寄存器:不是从控制线过来?控制一种是CPU对I/O模块的控制,要读/写,从控制信号过来;另一种是发给外部设备的命令,从数据线过来,同样的从外设获得的状态信息也从状态寄存器来,再从数据线返回
- 为什么混在一起?不会同时出现。获取状态和发控制命令是不会同时出现的(一般先后),可以复用
- 蓝色:和外设,涉及数据控制状态 不止一个外设所以有多组

- 并行接口:连多根线到外围设备 同时传多位数据
- 串行接口:只有一根线 每次只传输一位
- 串行用的更多:并行需要保持信息同步,走的一样快很难。1、本身不要走太远 2、两批数据间隔时间变长,不容易混在一起 要求线不能太长,频率不能太高 串行频率可以很高传很远

USB:通用串行总线
I/O操作技术

- 编程式:无中断 有处理器
- 中断驱动式:有中断 有处理器
- DMA:有中断 无处理器(处理器也会做事,但数据传送不需要)
编程式

- 读外围设备的状态 会等待 CPU始终在参与I/O这件事情 投入比例是100%
- 未就绪:要等等
- 就绪:从硬盘读取字,然后写到存储器 判断有没有结束
- 设备坏了:报错

读:从外设获得数据,写:传到外设

编址:
- 映射式:统一的地址空间 会占用地址空间
- 分离式:有存储器的线,也有I/O命令线,是分开的
中断驱动式

解决不断等待设备就绪的过程中消耗的时间
区别:向I/O模块发出读命令后,CPU可做其他事情 I/O准备好后会发起中断提醒CPU,CPU再检查
- 就绪:等待的任务交给I/O模块,等到数据读好后利用中弄断提醒CPU
- 出错

- 控制器的一个来源就是来自系统总线的控制信号
- 处理器会处理完更重要的事情然后来处理这个中断,然后获取这个数据

- 结束时会检查中断
- 保存现场,读数据字并存储,恢复现场并继续运行

- 保存:需要一段时间,过程中如果中断仍允许可能被打断,所以会禁止中断,安心保存现场,再允许,恢复同理也会禁止中断,再允许中断 正常情况下其实都允许
- 处理中断时允许吗?允许,否则中断响应后一直禁止了

响应优先级高:小伙子抢到座位 更快地抢到位置 多个中断谁会被最先响应
处理优先级高:小伙子会把位子让给老太太 最后地占有位置 看到小伙子会视而不见(只能看到处理优先级高的,处理优先级低或同级的会屏蔽掉) 新的中断来如果优先级高会切换响应
好几个中断一起来:从里面筛选处理优先级比自己高的,然后优先响应响应优先级最高的,但是最终抢到位置的是处理优先级最高的(在保存完现场打算处理时把中断允许后比较)

掩码字:表示谁可以屏蔽谁 (根据处理优先级来算) 所在行的能不能屏蔽列的 最低的只能屏蔽自己
中断服务程序:
- 主程序的优先级是最低的 L1(因为响应优先级最高)(保存后开中断,处理L1,会看看L3L4的处理优先级比不比L1高)(小红线包括保存、处理、恢复原来破坏的状态)
- 响应L3(响应优先级更高)L3保存现场后打开中断发现L4的处理优先级高,会切换到L4,处理完后切到L3,因为L2处理优先级低于L3,视而不见,恢复主程序的现场,刚恢复好发现L2在,处理L2

怎么知道哪一个设备发起中断?多个中断线:每条线还是要进一步分辨哪一个设备,还是要用三种技术
- 软件轮询:问哪个模块发生的中断
- 菊花链:统一的中断请求线,传到这了就响应一下
- 独立请求:特定的阶码和分析优先级

- 固定优先级
- 轮询次数
- 链接次序
- 中断控制器控制
直接存储器存取

I/O直接和存储器读写数据
- CPU等待I/O就绪花时间
- 传递数据时先到CPU,再从CPU传到主存,读写都一样,因为没有直接沟通的途径,所以需要CPU干预,只有CPU有控制功能,主存和I/O模块只能听令行事
- 能不能解放CPU?提高利用率,因为其实没干啥
需要特殊硬件——DMA模块,替换CPU:有计数,把CPU的功能剥离了,设计专门硬件

长流程图变得很短:向DMA交代要去读,然后CPU做其他事情,DMA处理完了数据交互后会发指令给CPU,此时CPU知道所有事情都做完了
其他麻烦:搬数据让给DMA了,指令在内存里,DMA在内存和I/O模块间搬数据,都会访问内存——一个内存应付两个设备,可能发生冲突,让给谁——DMA优先,因为通常连接高速数据,如果不快速处理就会被冲掉
交给DMA做:CPU告诉DMA从哪里读,读多长,CPU在初始化和结束的处理时都有一定的时间开销
内存访问
CPU停止法

把权限给DMA,DMA要用CPU就交出去,但CPU会被耽误 DMA如果始终在传输数据方法没问题,但有时候数据是一波一波来的,两波数据之间主存并没有被有效利用 所以适用于大块数据传输
周期窃取

I/O数据准备好了才会发请求给总线,才会迁移总线控制权
中间一段给CPU了,DMA只要不用就立刻交回去,交换频繁,坏处DMA每次要用都要向总线发请求,然后切换,会有开销 当然主存利用率会变大 适用周期大,然后数据一波儿一波儿
交替分时访问

每个存储周期一分为二,上半周期应对CPU,下半周期应对DMA 很强的假设:存储周期很长,CPU来得及DMA也来得及
DMA怎么连到总线上?
配置机制
单总线分离DMA

就是把编程式里CPU的部分变成DMA了
单总线集合的DMA-I/O

为一个或多个I/O模块配备专门的DMA,有单独通道,不根据总线和I/O通讯了,有专门的,减少对总线的占用
I/O总线

共用DMA,可以提升整体的利用率,扩展性好 加一个I/O也支持
DMA示例

一开始要查询传递参数设置,中断在硬盘上寻道、查找扇区,CPU才能将任务交给DMA。读写完成后发起中断让CPU做结束操作,并进行校验。比较高的参与度

不断发展:现在:I/O通道:有自己的处理器,有些指令专门为I/O设计
I/O处理器:增加一个局部存储器,发展为自治计算机
18 课程小结

透明:看不见 组织会影响结构

总线不在冯诺依曼里,是后来改进的
把CPU拆开,I/O拆开——5个
思想:存储程序 现在和数据一起存——区分程序和数据(指令周期的每个阶段来区分:取指是指令,间址是数据)

努力成为现实——带来很多正面影响 天气预报要超算 摄像头小

最重要——CPU性能
MIPS-防止做手脚MFLOPS->不同的方面
指令流水线、多核等都可以提高性能

钟 不同挪法——个数总是2^k
双精度不是很重要
填满数域的技巧:用00000000补小,用11111111补无穷(都是挪了一部分)
NBCD:0-9用四位数表示 1100 1101表正负

这里我好像忘光了
校验码不出错->数据不出错 不能直接用C’和D‘ 比C’和C’’(已知最多一位出错,D’没有出错,C‘则一定没有出错)??
- 奇:异或1 补上奇校验码有奇数个1 分清楚
- 偶:补上后有偶数个1
- 海明码:谁影响故障字 一位出错C 多位出错D
- 循环冗余校验CRC:生成多项式
CPU(算术)

下一条:PC
三地址(还有个结果)两地址(两个操作数)1(AC)0(栈)
间接:取两次
偏移分三种(忘了,待复习)
二义性:长的操作码不能解释为短的操作码
用0地址1地址2地址写程序、微操作序列等


引入中断:判断允许还是禁止,正常都是允许的(判断有无中断,有没有看得到的中断,处理优先级)
间址:取有效地址
微操作除了告诉干什么,还给时间——t1、t2…尽可能少,读和写等不能冲突,一个t谁先谁后没有影响
ICC:修改2位

时间尽可能相等
判断指标——加速比>1 没用的放上面 T1,n变长了:因为有些步骤不需要,存寄存器取出来等浪费时间
有跳转——下一条有效的第一个(读)和上一条有效的最后一个(写入)在一个时间线里,不冲突
(红框的不算了,只算到最后的??没听懂??)
旁路?nop 调整代码顺序
靠旁路一定解决数据冒险吗:不一定
控制冒险:开始的位置 不太可能一直在里面转圈,而是大多数预测准 一般就四个状态

公式怎么算,延迟分别是多少,怎么算

减法:CarryIn+1,选择进行取反
疑似一张A4纸考一道手算计算
Cache具体的过程肯定不考(没有不考Cache的意思)

按照图来,不一定按照32位来,可能8位等(ppt的例子)
保护位:右移时还在里面
舍入:不同模式

注意补偿+0110 看看结果对不对 要写过程
减法避免借位:反转操作 如果结果没有进1——还不上——反转加1

控制器的实现:输入->输出
- 硬布线:用布尔运算的形式算得控制信号 不能改
- 微程序:通过不同的地址实现跳转等,灵活 比较慢
- 具体的实现流程
存储


长了贵,短了不够用,看操作系统的需求 还有数据存在内存
总线:不能有两个源发送信息:冲突 两个都无了 只能有一个门打开

内存跟不上CPU速度
p是命中率 Tm主存时间 第二行式子好算

LRU:使用的时间
LFU:使用的次数

存储器类型——背!!不同的区别 ROM可以写,出厂是ROM,自己写一次是DROM,整片整片擦、按字节擦,最后按块擦比较常用——快闪存储器
存储阵列:位扩展(人多了)、字扩展(房间数多了)….行地址列地址怎么选中(行译码器)

磁头离得更近,做的更小,盘子的密度更高,可以读写小位数的
双磁头
柱面
输出数据的速度要尽可能稳定
好几个磁道划一个扇区
光盘:螺旋线,从头到尾一根线,恒定线速度,所以时快时慢,里面慢外面块 DVD:坑更小
磁带顺序读

多个磁盘合起来提高容量

分页的逻辑:忘了 TLB当前要用的页放进去??
逻辑地址->物理地址(快表->页表 缺页到硬盘) 拿数据(Cache->主存)
总线

复用->线变少,浪费时间
节省时间:不复用 不在乎时间:复用
仲裁:集中式(仲裁器,计数器查询解决出现故障的问题)/分布式(自举式优先排好序,最低和总线连着)
不可以两个设备发信号,别人用总线优先级高不能抢(与中断不同)

算数据传输率(同步、异步)
输入输出

串行好:速度高,距离远
编程式:100% 运行一段程序
中断:解决等设备就绪的问题(优先级的例子)不会画图但是会写流程(从哪里来回哪里去,看保存的是什么恢复到哪里,主存才能看到被屏蔽的中断请求) 响应和处理
DMA:解决搬数据的问题 也会用中断(磁盘的例子)CPU让DMA(高速数据传输设备)

