寄存器重命名
- 概述
- 寄存器重命名的方式
- 使用 ROB 进行寄存器重命名 (Intel 多采用)
- 将 ARF 扩展进行寄存器重命名
- 使用统一的 PRF 进行寄存器重命名
- 总结
概述
- 数据相关性 (寄存器相关)
- WAW
- WAR
- RAW
- 存储器数据的相关性
- WAW
- WAR
- RAW
- 控制相关性
- 分支指令引起,分支预测可以解决
- 结构相关性
- 处理器当中部件可以使用才可以继续执行
WAW 和 WAR 相关性可以通过修改寄存器名字,但依旧存在的原因
- 有限的寄存器个数
- 循环体(重复写入,消耗大量寄存器名)
- 代码重用,和循环体类似
而直接新增通用寄存器,会导致之前编译好的程序需要重新编译
为什么会被消耗完?
因为一条指令可能会用 3 个寄存器,一次 4 条指令,流水线长度 12,那么 48 * 3=144 个寄存器
指令一多,还是会被消耗的
采用新增物理寄存器
- 重命名映射表
- 保存目前已有的映射表
- 空闲寄存器列表
- 等待使用的映射表
寄存器重命名的方式
使用 ROB 进行寄存器重命名 (Intel 多采用)
每条指令按照程序中原始的顺序存储到 ROB 中,当指令结果计算出来后,会写到 ROB 中,但由于分支预测、异常、相关问题,结果未必正确,所以是推测的 speculative
一条指令会一直保存在 ROB 中,只有当指令变为流水线中最旧的指令,并且检验正确时,才会离开 ROB,同时更新处理器状态寄存器、将结果写入到 ARF 中
也就是将 PRF 加在写入 ARF 之前
需要指示目前目的寄存器的值是在 ARF 还是 ROB 中
问题
- 很多指令没有目的寄存器(约占 25%),但仍会占用 entry,造成浪费
- 对于一条指令来说,ROB 和 ARFF 都有可能读取源操作数,为了支持最坏情况,ROB 和 ARF 都端口会很多。4-way 的超标量处理器,1 条指令的源寄存器有 2 个,则 ARF 和 ROB 都支持 2X4 = 8 个读端口
优点
- 设计复杂度不高,简单
将 ARF 扩展进行寄存器重命名
将 PRF 设置为单独的存储空间 FIFO
存储顺序和 ROB 重命名方式一致
使用统一的 PRF 进行寄存器重命名
源寄存器
- 查重命名映射表
目的寄存器 - 指定空闲状态的物理寄存器,如果全满,则表示全部占用,所有阶段暂停
外部查看处理器状态是,很多物理寄存器处于 speculative,尚未提交时,则不能被外界看到,只有退休时才能看到,需要添加另外一套 RAT 来查询状态
什么时候物理寄存器退休呢?
- 识别最后一次使用它的指令完成即可
- 但不是一个直接的事情
当执行完 B MUL 指令时,则可以将 P1 给释放了,不需要再保留 R1 了
ROB 需要保存当前对应的物理寄存器之外,还需要存储之前对应的物理寄存器
总结
基于 ROB 的重命名 | 将 ARF 扩展进行寄存器重命名 | 使用统一的 PRF 进行寄存器重命名 | |
---|---|---|---|
控制逻辑复杂度 | 简单 | 适中 | 复杂 |
内容 | 每个 entry 都分配项,不需要管理 PRF | PRF 为单独 FIFO | Freelist 管理空闲表,2 个 RAT(映射当前、上一个) |
什么时候占用 PRF | 所有指令都分配项 不需要管理 PRF | 带有目的寄存器指令分配项 | 带有目的寄存器指令通过 freelist 管理 |
什么时候释放 | ROB 释放,PRF 移动到 ARF 里 | ROB 释放,PRF 移动到 ARF 里 | 两个 RAT 映射重叠 |
释放去向何处 | 空置 | FIFO 管理 | Freelist 管理 |
特点 | 移动两次 | 移动两次 | 移动一次,查询只需要一次(大大降低功耗) |