ROB是超标量处理器内部的一个硬件部件,一般是一个FIFO的队列,进入处理器的指令顺序
进入ROB,所以ROB里的指令顺序就是处理器内部指令的年龄顺序。注意,这里说的进入处理器
内部的指令就包括投机执行的指令,这个和软件看到的正常执行的指令是不一样的。
1 | young old |
如上指令按照insn_1->insn_6的顺序顺序进入ROB,正常执行完的指令按照同样的顺序离开
ROB,也就离开了处理器。
但是,ROB里的指令也可能不按照先入先出的顺序离开,当投机执行错误,需要flush掉指令
时,处理器会抹去最年轻一段指令,这时就是年轻指令先离开。其中典型的例子就是分支预
测错了,比如上面insn_4是一个分支指令,某个时刻发现insn_4的分支预测做错了,也就是
insn_5/6取错了,那就要把insn_5/6从ROB里去掉,新取入的指令(insn_7/8)占据insn_5/6
的位置。
1 | young old |
硬件里各个部件是并行在运行的(软件工程师有时会忽略这一点),有哪些在同步操作ROB的硬
件部件呢?具体行为又是怎么样的?
- 指令进入ROB
指令rename后就会根据ROB上的指令进入点标记(allocate)写入ROB。
- 指令正常离开ROB
控制指令退休的部件(一般就是ROB自己控制)在一拍中要检测指令可以退休,如下commit位置
表示待提交指令的位置,如果处理器一拍可以提交两条指令,insn2/1又都满足退休条件,
insn2/1就可以都在这一拍里被提交,提交后的指令状态为retired,相当于离开了流水线,
指令对寄存器和内存(cache)的改动也变成外部可见。
- 指令被flush离开ROB
指令被flush离开流水线需要对流水线中很多部件做flush操作,清空里面和被flush指令相关
的信息,ROB是其中一个需要被flush的硬件部件,这里对ROB的操作主要就是更新ROB上指令
进入点的标记。可见flush指令会和指令进入ROB存在同步问题,逻辑上应该先flush掉ROB中
的指令再把新指令写入ROB。
1 | young old |
ROB里allocate和commit之间(包括commit)的指令是当前正在处理器里执行的指令,这些指令
可能正在等资源,可能正在执行,也可能已经执行完毕正在等退休,但是这些指令的都是投机
执行的,在commit阶段处理器判断是正确执行的指令才可以退休。当这些正在处理器里运行的
指令在某个状态发现投机不对时就会触发指令的flush。