从零开始学RISC:第十七篇
提交与写回
什么是提交、什么是写回?在五级流水线的顺序单发射CPU中,似乎“提交”就是在“写回”级进行的。但实际上,这并不是一回事。
说文解字
- 写回(writeback, WB):结果已经算出来了,准备写回某个存储体,最常见是写回寄存器堆。
- 提交(commit / retire):这条指令被体系结构正式承认“已经执行完成”,它的效果从这一刻起对软件可见,且不会再因为乱序、异常预测错误等原因被撤销。
说白了,写回是“结果产生并回填”;提交是“结果正式生效”。
遵守顺序
对于顺序执行的CPU,写回就是ALU / Load / CSR 指令的结果,它们会写到通用寄存器堆xN里面。此时因为流水线是顺序执行、顺序完成,写回和提交几乎可以看成同时发生。
但对于乱序CPU,或者是多发射的呢?写回通常不是直接写“架构寄存器”,而是写到ROB[1]或PRF[2]。在这种情况下,写回表示“计算结果已经准备好”,但这条指令还不一定已经提交。
对于提交,重点不在“提”而在“交”,也就是说,结果交上去之后,一切就尘埃落定。
提交表示这条指令已经满足以下条件:
- 它之前的所有更老指令都已经处理完毕
- 它自己已经执行完成
- 没有更老的异常、错误预测、冲刷需要撤销它
- 它的架构效果现在正式生效
“架构效果”包括:
- 整数寄存器更新
- 浮点寄存器更新
- CSR 修改
- Store 对内存真正可见
- PC 按正确程序顺序前进
- 指令计数器、异常精确性得到保证
因此,提交本质上是保证 CPU 对外表现得像一条一条按程序顺序执行。
指令也有后悔药
如果“写回”就等于“最终生效”,那会出大问题,比如遇到了指令异常等,无法处理。
举个例子:
1 | add x5, x1, x2 |
乱序 CPU 里,第 3 条可能比第 2 条更早算完,甚至先写回到物理寄存器。但是如果第 2 条触发异常,那么第 3 条虽然写回过,却不能提交;最终它必须被撤销。这说明,写回不代表指令一定完成,提交才代表不可撤销。
严重的问题:乱序提交
ISA规范要求:指令必须按照顺序提交。
我们回过去看一下 之前 的仿真波形:
黄色区域对应的代码为:
1 | # ======================================== |
发生了什么?
在mul x9, x8, x6计算结果被提交之前,下一行addi x10, x0, 3便已经提交了,改变了ISA的寄存器对外可见状态!这样是错误的。
因此,我们只能给乘法器加上阻塞,即处理乘法时,后面的指令全部阻塞。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Esing的小站!
评论
WalineGitalk


