文章目录
- 体系结构通识
- 冯诺依曼架构:计算单元+存储器+输入/输出设备+控制器
- 程序的编译过程:预处理-编译-汇编-链接
- 预处理器:替换宏定义和头文件为具体的函数或者内容
- 编译器:将`高级程序`语言(C语言)替换为`低级通用`的程序语言(汇编语言)
- 汇编器(Assembler):将低级通用程序语言(汇编语言)替换为`机器能理解`的`字节码`(二进制串)
- 链接器:外部函数的符号解析和地址重定位(确定外部函数对应`所在程序的地址`)
- 内存地址和字节
- 字节-寻址的内存组织结构:视同为`字节数组`,寻址单位`为1个字节`
- 寻址单位:每一个内存地址代表几个字节,例如`2字节寻址`
- 32位系统和64位系统:代表`逻辑地址的位数`,`虚拟内存空间`的大小
- 字节排序:大端法和小端法
- 大端法:最不重要的字节在高位-顺序存储
- 小端法:最不重要的字节在低位-逆序存储,`更加常用`
- 字符串的表示:字符用ASCII码(1字节)表示,使用空字符'\0'(null character,'0x00')表示终止
- 整数的表示:有符号数和无符号数,符号位
- 原码,补码和反码:`默认使用二进制补码`表示`有符号整数`
- 位数的扩展:有符号和无符号数
- 无符号整数-零扩展:直接前面补0,不影响符号位
- 有符号整数-符号扩展:扩充k位,前面`填充k个原先的最高位`,不影响结果
- 截断:超出数据范围
- 加法运算:有符号加法和无符号加法
- 无符号加法:mod2 w 2^{w}2w即可
- 有符号加法:正溢出和负溢出
- 乘法运算
- 有符号整数的`通用方法`:`先定符号位`,`转正数`,使用`算盘法`求解,最后构造有符号整数(是负数则取反+1)
- 二进制拆分法:a ⋅ b = a < < ( x 0 ⋅ 2 0 + x 1 ⋅ 2 1 + ⋯ x w − 1 ⋅ 2 w − 1 ) a\cdot b=a<<(x_0\cdot 2^0+x_1\cdot 2^1+\cdots x_{w-1}\cdot 2^{w-1})a⋅b=a<<(x0⋅20+x1⋅21+⋯xw−1⋅2w−1)
- 二的乘法:左移k位
- 二的除法:右移k位,右移后`空出位全部填充符号位`
- 浮点数的表示
- `IEEE标准表示法`-二进制科学计数法:符号位s ss,指数部分E EE和有效数部分M MM
- 指数位的偏置:偏置一般设置为2 k − 1 − 2 = 2 7 − 2 = 126 2^{k-1}-2=2^{7}-2=1262k−1−2=27−2=126,排除2种特殊情况,全0和全1,float32中E EE的范围为[-126,127]
- 规格化值:指数位非特殊情况(全0或者全1),有效数定义为M = f + 1 M=f+1M=f+1,f为尾数转小数
- 非规格值:指数位全为0,有效数定义为M = f M=fM=f,f为尾数转小数
- 无穷值:指数位全为1,但是`尾数全为0`,`特殊定义值`。
- 非有效数字NaN:指数位全1,但是尾数`非0`,`特殊定义值`。
- 舍入-rounding:浮点数只能近似表达某些实数,涉及到近似到`具体小数位` / `整数`的问题
- 浮点数加法:`变为规范数`,对齐指数部分,还原为浮点数表示
- 浮点数的乘法:`变为规范数`,计算重要数的乘法结果,还原为浮点数表示
- 机器级别的编程:常见汇编指令-未完待续
- 处理器架构:以Y86-64为例
- 指令集
- 时序电路执行阶段:取指-译码-执行-内存-写回-更新程序计数器
- 取指:从指令内存中根据PC取出指令
- 译码:读取指令类型和操作数
- ALU:返回计算结果
- 软件角度优化程序性能
- 循环展开
- 增强并行性
- 程序的局部性:时间局部性和空间局部性
- 主存储器
- 非易失存储器:断电不会丢失数据
- PROM:只可以被编程一次
- *ROM:"只读"存储,实际上`可读可写`。
- EEPROM:可读可写,例如闪存(手机存储和SSD)。
- 易失存储器:断电会丢失数据
- RAM:随机访问内存
- DRAM:依靠电容器存储状态,电容器电量会流失,需要`定期刷新`;速度较慢,但容量大
- 存储单位为单元/超单元,16x8的DRAM芯片表示16个单元,每个单元8个bit
- SRAM:使用双稳态晶体管存储状态,不需要定期刷新;速度快但造假昂贵
- 存储器架构:L0(CPU寄存器)-L1/L2(SRAM)-L3(DRAM)-L4+(磁盘或者SSD)
- 存储器层次中的"缓存"
- 缓存交换抽象原理:不同级别存储(例如L1和L2),以`数据块`为单位交换缓存;缓存命中和缓存不命中。
- 缓存未命中:冷启动(启动时无缓存),映射冲突(`哈希冲突`,相互覆盖)和容量冲突(需要`缓存太多数据`)
- 高速缓存存储器的通用架构
- 缓存行与组:( S , E , B , m ) (S,E,B,m)(S,E,B,m),S代表组数,E代表缓存行,B代表数据块大小(字节),m代表内存地址的位数,t = m − s − e t=m-s-et=m−s−e代表标记位数,用于区分同一组不同缓存
- 直接映射缓存:E = 1 E=1E=1,每一个组只对应一个缓存行,根据s ss,有效位和标记位t tt确定缓存是否存在
- 组相联映射缓存:E > 1 E>1E>1,每一个组对应多个缓存行,根据s ss,有效位和标记位t tt对缓存行进行`一一匹配`,确定缓存是否存在。
- 全相联映射缓存:S = 1 S=1S=1,只有一组,包含E > 1 E>1E>1个缓存行;使用有效位和标记位t tt并行地进行匹配,不需要组数位s ss。例如`TLB快表`。
体系结构通识
冯诺依曼架构:计算单元+存储器+输入/输出设备+控制器
程序的编译过程:预处理-编译-汇编-链接
预处理器:替换宏定义和头文件为具体的函数或者内容
- 有宏定义
#Define A B,将代码中A变量全部替换为B。 - 替换为头文件
stdio.h为对应的函数声明:例如extern int printf('xxxx')
编译器:将高级程序语言(C语言)替换为低级通用的程序语言(汇编语言)
汇编器(Assembler):将低级通用程序语言(汇编语言)替换为机器能理解的字节码(二进制串)
链接器:外部函数的符号解析和地址重定位(确定外部函数对应所在程序的地址)
内存地址和字节
字节-寻址的内存组织结构:视同为字节数组,寻址单位为1个字节
寻址单位:每一个内存地址代表几个字节,例如2字节寻址
32位系统和64位系统:代表逻辑地址的位数,虚拟内存空间的大小
字节排序:大端法和小端法
大端法:最不重要的字节在高位-顺序存储
小端法:最不重要的字节在低位-逆序存储,更加常用
字符串的表示:字符用ASCII码(1字节)表示,使用空字符’\0’(null character,‘0x00’)表示终止
chars[6]="12345";地址 内容(字符)ASCII1000'1'0x311001'2'0x321002'3'0x331003'4'0x341004'5'0x351005'\0'0x00整数的表示:有符号数和无符号数,符号位
原码,补码和反码:默认使用二进制补码表示有符号整数
*正数转负数技巧:正数取反+1=负数
反码-二进制反码:最高位为符号位,数值为− x w − 1 ⋅ ( 2 w − 1 − 1 ) -x_{w-1}\cdot(2^{w-1}-1)−xw−1⋅(2w−1−1)
- 正数的补码为其本身,负数的补码为正数的原码取反得到。
补码-二进制补码:最高位为符号位,数值为− x w − 1 ⋅ 2 w − 1 -x_{w-1}\cdot2^{w-1}−xw−1⋅2w−1
- 补码=反码+1
位数的扩展:有符号和无符号数
无符号整数-零扩展:直接前面补0,不影响符号位
有符号整数-符号扩展:扩充k位,前面填充k个原先的最高位,不影响结果
- 符号为0,显然成立
- 符号为1,扩充的位数得到的负数恰好就是扩充之前得到的负数。
截断:超出数据范围
加法运算:有符号加法和无符号加法
无符号加法:mod2 w 2^{w}2w即可
有符号加法:正溢出和负溢出
乘法运算
有符号整数的通用方法:先定符号位,转正数,使用算盘法求解,最后构造有符号整数(是负数则取反+1)
0101×0011-------------0101(0101×1)01010(0101×1<<1)00000(0101×0<<2)00000(0101×0<<3)-------------01111二进制拆分法:a ⋅ b = a < < ( x 0 ⋅ 2 0 + x 1 ⋅ 2 1 + ⋯ x w − 1 ⋅ 2 w − 1 ) a\cdot b=a<<(x_0\cdot 2^0+x_1\cdot 2^1+\cdots x_{w-1}\cdot 2^{w-1})a⋅b=a<<(x0⋅20+x1⋅21+⋯xw−1⋅2w−1)
二的乘法:左移k位
二的除法:右移k位,右移后空出位全部填充符号位
浮点数的表示
IEEE标准表示法-二进制科学计数法:符号位s ss,指数部分E EE和有效数部分M MM
- 计算公式为:
V = ( − 1 ) s ⋅ M ⋅ 2 E \begin{align} V=(-1)^s \cdot M \cdot 2^E \end{align}V=(−1)s⋅M⋅2E
指数位的偏置:偏置一般设置为2 k − 1 − 2 = 2 7 − 2 = 126 2^{k-1}-2=2^{7}-2=1262k−1−2=27−2=126,排除2种特殊情况,全0和全1,float32中E EE的范围为[-126,127]
规格化值:指数位非特殊情况(全0或者全1),有效数定义为M = f + 1 M=f+1M=f+1,f为尾数转小数
非规格值:指数位全为0,有效数定义为M = f M=fM=f,f为尾数转小数
无穷值:指数位全为1,但是尾数全为0,特殊定义值。
非有效数字NaN:指数位全1,但是尾数非0,特殊定义值。
舍入-rounding:浮点数只能近似表达某些实数,涉及到近似到具体小数位/整数的问题
浮点数加法:变为规范数,对齐指数部分,还原为浮点数表示
浮点数的乘法:变为规范数,计算重要数的乘法结果,还原为浮点数表示
机器级别的编程:常见汇编指令-未完待续
处理器架构:以Y86-64为例
指令集
时序电路执行阶段:取指-译码-执行-内存-写回-更新程序计数器
取指:从指令内存中根据PC取出指令
译码:读取指令类型和操作数
ALU:返回计算结果
软件角度优化程序性能
循环展开
增强并行性
程序的局部性:时间局部性和空间局部性
- 时间局部性:在相邻时间访问同个数据
- 空间局部性:倾向访问相邻的元素
主存储器
非易失存储器:断电不会丢失数据
PROM:只可以被编程一次
*ROM:"只读"存储,实际上可读可写。
EEPROM:可读可写,例如闪存(手机存储和SSD)。
易失存储器:断电会丢失数据
RAM:随机访问内存
DRAM:依靠电容器存储状态,电容器电量会流失,需要定期刷新;速度较慢,但容量大
存储单位为单元/超单元,16x8的DRAM芯片表示16个单元,每个单元8个bit
- 通过内存控制器索引DRAM的supercell,按照二维结构组织,分别需要行索引和列索引
- 每次进行行索引时,会将这一行的supercells全部缓存下来。
- 可以通过叠加多个DRAM芯片的方式一次性索引更多字节,例如1字节*8=8字节。
SRAM:使用双稳态晶体管存储状态,不需要定期刷新;速度快但造假昂贵
存储器架构:L0(CPU寄存器)-L1/L2(SRAM)-L3(DRAM)-L4+(磁盘或者SSD)
存储器层次中的"缓存"
缓存交换抽象原理:不同级别存储(例如L1和L2),以数据块为单位交换缓存;缓存命中和缓存不命中。
- 缓存:SRAM,以数据块的形式存储和交换数据