总线
总线的作用
- 提供对外统一的接口,便于外围设备连接
- 减少不同电路元件通信的线路成本
* 使用IO总线,如增加一个IO设备只需要连接到IO总线上,有IO总线与其他要通信的部分相连
总线的例子
USB
PCI
总线- Thunderbolt总线
总线的分类
* 片内总线
* CPU内部的总线,如高速缓存(寄存器)、控制器、运行器、中断系统的线路连接
- 系统总线
- CPU、主存、IO设备、各组件之间的信息传输线
- 数据总线
数据总线位数一般与CPU位数相同(32、64)
一次传输的数据就是总线位数 - 地址总线
寻址范围是 [ 0 , 2 n ] [0, 2^n] [0,2n](n表示地址总线位数) - 控制总线
- 数据总线
- CPU、主存、IO设备、各组件之间的信息传输线
总线仲裁
why
为了解决多个主模块同时竞争总线控制权的问题
how
-
链式查询
-
计时器定时查询
-
独立请求(常用)
what
设备和仲裁器中间如何进行应答是设计的关键,
主模块向仲裁器发出请求信号(通过一条BR线(总线请求信号线))
仲裁器顺序遍历连接在授权信号线(通过一条BG线(总线授权信号线))的主模块,响应第一个有请求的主模块
计时器定时查询增加了计时器和地址线,可以通过改变计时器的初值改变响应优先级
最后的独立请求就是每个主模块都有自己的BR和BG,仲裁器可以采用特点的算法决定先响应谁的请求
IO设备
中断响应(异步思想的一种体现),DMA(直接存储器访问)
内存
主存
RAM通过电容存储数据,每隔一段时间要刷新电容,断电会丢失数据
32位操作系统内存最多只有4GB,因为地址总线的寻址范围是0~2^32
缓存
局部性原理(时间、空间)
缓存置换算法
- 随机
- FIFO:维护队列
- LFU(最不经常使用):记录频率
- LUR(最近最少使用)
辅存
对磁盘的访问总是由缺页引起
硬盘也有缓存
磁道访问算法
- 先来先服务
- 最短寻道时间优先
- 电梯算法(扫描算法)
- 循环扫描算法
存储单位
字
字块:缓存的置换是以字块为单位的吗
簇:文件的占用空间和实际大小不同
CPU与cache之间的数据交换是以字为单位,而cache与主存之间的数据交换是以块为单位。一个块由若干字组成,是定长的。
指令系统
- 机器指令的形式
- 操作码+地址码
- 操作码指明要操作的类型
- 操作码位数表明机器的操作种类数2^n(n表示操作码位数)
- 三地址码指令
- 二地址码指令
- 一地址码指令
- 零地址码指令
- 机器指令的操作类型
- 数据传输
- 算法逻辑
- 移位指令
- 控制指令
- 机器指令的寻址方式
- 指令寻址
- 顺序寻址
- 跳跃寻址
- 数据寻址
- 立即寻址(指令直接获得操作数,无需访问存储器,操作数大小受指令地址码位数限制)
- 直接寻址(指令中是操作数的主存地址,寻址范围受指令地址码位数限制)
- 间接寻址(指令中是操作数地址的地址,需要多次访问内存)
指令执行
流水线时间
进制
有限的符号表示无限的数值,常见的有10进制(0~9个符号),60进制(符号个数比较特殊如时间),16进制(地址)
2进制转10进制
位权展开法
整数转2进制
除二取余,逆序排列;笔试更加常用的是列出 2 4 8 16 32 一个个减
小数转2进制
乘二取余,顺序排序
原码
- 最高位为符号位,0表示正数,1表示负数
- 优点:利于人类阅读
- 缺点:符号位不参与计算,计算较为复杂,0有2种表示
- 原码的计算:待补充
补码
正数的补码等于原码,负数的补码等于
2
n
+
1
+
x
2^{n+1}+x
2n+1+x ; n
表示负数的位数,x
表该数
补码存在的意义
补码就可以消除运算中的减法操作
eg:x = -13, 假设数字有8个bit存储
x的原码: 1000_1101
x的补码: 1_0000_0000 + (-13)
= 1_0000_0000 - 1000_1101
= 1111_0011
有了补码就可以消除运算中的减法操作,
eg: 假设数字用8个bit存储
14 - 13
= 14 + (-13)
= 0000_1100 + 1111_0011
= 1111_1111
= -1
10 - 13
= 10 + (-13)
= 0000_1010 + 1111_0011
= 1_1101
= 1111_1101
= -3
补码的原理
比如现在是6点,想要回到3点,可以逆时针拨动3个单位,也可以顺时针拨动(12-3)= 9个单位
一些有用的补码数
// 0的补码:0000_0000
// -1的补码:1111_1111
// 由于计算机存储数字时采用补码,C语言中有一个memset方法可以按字节赋值,所有0,-1可以用memset赋值
#include<stdio.h>
#include<string.h>
int main()
{
int a[10];
memset(a, 0, sizeof a);
memset(a, -1, sizeof a);
return 0;
}
小数的补码
正数不变,负数 = 2+x ( x<0 && x >= -1)
原码:1-0.01011 (1-表示符号位)
反码:1-1.10100
补码:1-1.10101
反码
定义:正数的反码等于原码,负数的反码等于 2^(n+1)-1+x n表示负数的位数
反码存在的意义
由原码求反码时还是采用了减法,而且是溢出了的减法,所以反码的出现是为了方便原码转补码
补码 = 原码除符号位外取反(反码) + 1
定点数
定点数: 固定小数点到某个位
纯小数:符号位后是小数点 eg: 0.101, 0.001
纯正数:数值位最后 eg: 1234.0, 54.0
其他数:乘以比例因子
数值 | 符号位 | 数值位 |
---|---|---|
0.1011 | 0 | 1011 |
-0.1011 | 1 | 1011 |
1011 | 0 | 1011 |
-1011 | 1 | 1011 |
浮动数
表示格式
类比科学计数法 123450000 = 1.2345 × 1 0 8 123450000 = 1.2345 \times 10^{8} 123450000=1.2345×108
1.2345 = 尾数; 10 = 基数; 11:阶码;
N = S × r j N = S \times r^j N=S×rj
S:尾数
r:基数
j:阶码
数值 | 阶码符号位 | 阶码数值位 | 尾数符号位 | 尾数数值位(必须纯小数,第一位必须是1) |
---|---|---|---|---|
11.0101 = 0.110101 × 2 10 11.0101 = 0.110101 \times 2^{10} 11.0101=0.110101×210 | 0 | 10 | 0 | 11010100 |
11.0101 = 0.0110101 × 2 11 11.0101 = 0.0110101 \times 2^{11} 11.0101=0.0110101×211错误 | 0 | 11 | 0 | 01101010 |
表示范围
假设阶码数值取m位,尾数数值取n位
阶码的表示范围为:
[
−
(
2
m
−
1
)
,
2
m
−
1
]
[-(2^m-1), 2^m-1]
[−(2m−1),2m−1]
尾数的表示范围:
[
−
(
1
−
2
−
n
,
−
(
2
−
n
)
)
]
[-(1-2^{-n}, -(2^{-n}))]
[−(1−2−n,−(2−n))],
[
2
−
n
,
1
−
2
−
n
]
[2^{-n}, 1-2^{-n}]
[2−n,1−2−n]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xBORnAHa-1627050081451)(Untitled.assets/image-20210720231714519.png)]
规格化
- 尾数必须是纯小数
- 尾数的最高位必须是1
原码 = 反码 = 补码:x = 0.0001101000 (二进制)
浮动数规格化:x = 0.1101000 * 2^-3 (二进制混十进制)
尾数符号位:0; 尾数数值位:1101000; 阶码符号位:1; 阶码数值位:-3 = 0b11
数值 | 阶码符号位 | 阶码数值位(4位) | 尾数符号位 | 尾数数值位(10位)(必须纯小数,第一位必须是1) |
---|---|---|---|---|
0.0001101000 | 1 | 0011 | 0 | 11_0100_0000 |
eg: 设浮动数字长为16位,阶码为5位,尾数11位,将十进制 − 54 -54 −54表示为二进制浮点数。
原码:x = 1000_0000_0011_0110
浮动数规格化:x = -0.11_0110 *
2
110
2^{110}
2110 (都是二进制)
尾数后面加0,补充到10位:1101_1000_00
取反:0010_0111_11
反码:0010_1000_00
于是尾数数值为应当存储反码形式的:0010_1000_00
尾数符符号位:1
阶码数值位向前补0,补充到4位:0110
阶码符号位:0
数值 | 阶码符号位 | 阶码数值位(4位) | 尾数符号位 | 尾数数值位(10位)(必须纯小数,第一位必须是1) |
---|---|---|---|---|
− 54 -54 −54 = − 0.110110 × 2 110 -0.110110 \times 2^{110} −0.110110×2110 | 0 | 0110 | 1 | 0010_1000_00 |
计算机一般使用浮动数
浮点数加减法运算
对阶 -> 尾数求和 -> 尾数规格化 -> 舍入 -> 溢出判断
x
=
0.1101
×
2
01
x = 0.1101 \times 2^{01}
x=0.1101×201
$ y = -0.1010 \times 2^{11}$
对阶
x
=
0.001101
×
2
11
x = 0.001101 \times 2^{11}
x=0.001101×211
$ y = -0.1010 \times 2^{11}$
阶码符号位 | 阶码数值位 | 尾数符号位 | 尾数数值位 |
---|---|---|---|
00 | 00 | ||
00 | 0011 | 11 | 1010 |
太麻烦了省略。。。
浮点数加减法流程
编程相关的浮动数知识
-
浮点数存在上溢和下溢
-
浮点数存在误差,尤其是大数和小数进行运算时,因为对阶会截断某些位数
-
java
中的double
,long
类型不满足原子性,所以可能线程不安全 -
浮点数(IEEE 754标准)注意误差(eps = 10-6取代替等于)
* float: 32位 sign: 1 exp:8 frac:23 * 大概是2^(8-1)-1 = 127 = 2^127 = 10^38这个级别 * double 64位 sign: 1 exp:11 frac:52 * 大概2^(11-1)-1 = 1023 = 2^1023 = 10^307级别