现代微处理器体系结构简介
指令集架构

存储器层次结构
硬盘(os) -> 内存(os) -> 缓存(硬件) -> 寄存器(编译器)
编译器可以管理寄存器
尽可能少的访问寄存器以外的存储器
- 寄存器的数量有限
- 对缓存的利用,对大型数据结构有用
地址空间
- 代码区
- 存放目标代码
- 静态数据区
- 全局变量
- 静态变量
- 部分常量,例如字符串
- 动态内存区
- 也被称为内存堆
- 程序员管理:c,cpp
- 程序自动管理:java,ada
- 程序运行栈
- 活动记录
- 函数调用的上下文现场
寄存器的分配和指派
why?
- 速度快
- 某些运算只能发生在寄存器中?()
- 优化指令的执行,更希望所有的指令都在寄存器中完成
- 寄存器有很多好处,然后确实有限
种类
- 通用寄存器
- 保留寄存器(专门用途,特定功能):栈指针,返回地址寄存器
- 临时寄存器‼️:调用方保存的寄存器
- 全局寄存器‼️:被调用方保存的寄存器
- 专门寄存器
全局寄存器分配
“全局”是相对于“基本块”而言的
分配原则:
- 垮基本块仍然活跃的变量,尤其是循环体内
局部变量参与全局寄存器分配 - 寄存器专属于线程!为了线程安全,全局变量/静态变量一般不参与全局寄存器分配
1 | void foo(int a) |
?(为什么全局变量不参与)
分配方法
- 引用计数:根据被引用次数,赋予权重,由大到小分配寄存器
- 着色图算法:构建变量之间的冲突图,将不同的全局寄存器分配给有冲突的变量(如果两个元素有边就要分配不同的寄存器)
引用计数
直接看次数,如果有循环体可以预先分配循环次数
‼️不再使用的变量无法及时释放寄存器
解决办法:活跃变量分析,冲突图;着色算法
图着色算法
简化版
- 构建冲突图
- 有k个寄存器,用k个颜色填充
活跃变量分析:看in[B]即基本块入口处的活跃变量

启发式着色算法
- 找到一个连接边小于k的节点,将其从图中移除
- 重复上面的步骤
- 按照节点被移走的反向顺序,重新构建填充颜色
⚠️如果找不到连接边小于k的节点,就在图中选取适当的结点,将它记录为“不分配全局寄存器”的结点,并从图中移走
临时寄存器的分配
- 基本块内使用
- 不得跨用函数调用
- 管理方法:维护寄存器池
指令选择(感觉不太重要)
(想补充补充补充)