处理器结构--ReorderBuffer
ReorderBuffer的作用
Reorder Buffer用来保存在乱序执行之前的(OOOE)指令执行顺序,当指令集合在乱序执行后按照原有指令顺序将结果提交。
ROB会将指令按照原有程序的顺序保存,这些指令会在被dispatched后添加到列表的一端,而当他们完成执行后,从列表的另一端移除。通过这种方式,指令会按他们dispatch的顺序完成。
实现方案
ROB的一种实现方案是环形缓冲区(类似于操作系统的IO缓冲区)。
在指令分发(dispatch)阶段在环形链表尾部增加指令集合。在指令完成阶段(complete)在头部增加从链表中移除的指令集。
- 当头指针(head)赶上尾指针(tail)的时候,ROB处于Empty状态。
- 当头尾指针都到了Buffer的末尾时,他们会再度环绕在最开始的指针处。
- 当尾指针环绕并且追上头指针时,Buffer就已经满了
在ROB中的每个Entry都必须包含足够的信息,使得在完成阶段可以知道该指令是否已经完成:
- Busy位
Busy位不是真正需要的,因为在complete阶段的头指针以及dispatch阶段的tail指针就是被用来追踪
busy
位所标志的Entries的 - Issued位 Issued位也可能不需要,因为在complete阶段不关心指令是否已经发射
- Finished位 Finished位是一个必要的信息,因为没有完成执行的指令是不允许进入complete阶段。当流水线的execution阶段把它的结果写到转发总线时,Finished位必须被写入。这也需要执行单元有一个指向ROB里面的每条已经完成的指令的指针。
当指令执行造成了异常时,指令地址必须保存下来。当异常被处理完后,PC寄存器将使用保存下来的指令地址重启。并且分支指令可能需要指令地址去决定PC寄存器去覆盖预测错误的分支。
重命名寄存器编号(Rename register number)对于完全知道重命名寄存器写入逻辑寄存器(Architected Register)也是有必要的。重命名寄存器编号能够用来检查重命名寄存器堆(RRF)中Valid
位,判断指令是否完成。这也使得Finished位没有必要了。
ROB会提供一个非常便捷的位置用来存储逻辑寄存器编号(Logical Register Number),Complete阶段也需要逻辑寄存器编号去写入逻辑寄存器中(Architected Register File)
- Speculative(预测)与Valid位 Speculative与Valid位也可能是不必要的,取决于如何从预测错误的分支覆盖的逻辑实现。推测指令永远无法到达重新排序缓冲区(ROB)的头部,因为之前的指令(包括分支)必须先完成。因此,分支将已经被解决,并且如果需要的话,在允许分支完成的任何(依赖于控制的)指令之前回复到初始状态。
如果在覆盖期间从重新排序缓冲器中移除控制依赖的指令,则不需要Valid位,否则,控制依赖指令必须被标记为无效,这样当它们到达重新排序缓冲器的头部时,它们可以被忽略。
流程
重新排序缓冲器的流程必须完成以下操作
- 分配:在dispatch阶段为程序顺序指令在重新排序缓冲区中保留空间
- 尾指针在重新排序缓冲器中选择一个位置
- 将必要的信息加载到ROB中(如指令地址,重命名寄存器,逻辑寄存器等)
- 尾指针自增
- 等待:Complete阶段必须等待指令执行完毕
- 在ROB头部的所有的指令全部执行完毕(finished),或者具有有效的重命名寄存器
- 第一个未完成的指令完全停止
- 完成:已结束(finished)指令允许将结果按顺序写入逻辑寄存器中(architected registers)。
- 将重命名寄存器的值copy到逻辑寄存器中
- 解除在重命名寄存器与逻辑寄存器之间的关系(将逻辑寄存器的Busy位设置成0)
- 解除ROB的关系(通过将头指针递增)
参考资料
环形缓冲区 Reorder Buffer Reorder Buffer: register renaming and in- order completion The Reorder Buffer 寄存器堆
- Java数据结构和算法(十四)——堆
- Java数据结构和算法(十五)——无权无向图
- Java数据结构和算法(十三)——哈希表
- Java数据结构和算法(十二)——2-3-4树
- UDF编程操作实现
- GitHub敏感信息扫描工具
- Java数据结构和算法(九)——高级排序
- Java数据结构和算法(十一)——红黑树
- Entity Framework Core 之数据库迁移
- 常见Web源码泄露总结
- 浅析Entity Framework Core2.0的日志记录与动态查询条件
- ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截)
- 【weakfilescan】敏感文件扫描工具
- ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法