指令流水线最耗时的是哪个阶段_CPU 不平衡流水线问题解决

文章介绍了乱序执行核心(OOO core)在指令流水线中的作用,通过拆解指令为微操作并利用Reorder Buffer和Reservation Station实现并行执行,缓解长指令和数据依赖带来的阻塞。尽管可能需要内存屏障确保顺序,乱序执行核心显著提升了处理器效率,甚至支持超线程技术。
摘要由CSDN通过智能技术生成

乱序执行核心(OOO core)

其实乱序执行的思想很简单:当下一条指令被阻塞的时候,从后面的指令里再找一条能执行的就好了嘛。但要完成这个工作却相当复杂。首先要保证程序的最终结果与顺序执行一致,同时要识别各类数据依赖。要达到理想的效果,除了并行执行之外,还需要对指令的粒度进一步细化,以达到以无厚入有间的效果,这样就引入了“微操作”(micro-operations, μ-ops) 的概念。在流水线的 Decode 阶段,汇编指令又被进一步拆解,最终的产物就是一系列的微操作。

f8f51691a516dc9e7d4f9953a0d4bb41.png

上图就是引入乱序处理核心之后的指令μ-ops 处理流程。不同颜色的模块对应第一张图中不同颜色的流水线处理阶段。

Fetch 阶段没有太多变化,在 Decode 阶段,可以并行对四条指令解码,解码的最终产物就是上面提到的μ-ops。后面的 Register Alias Table 和 Reorder Buffer 可以当做是乱序执行核心的预处理阶段。

对于并行执行的微操作,或者乱序执行的操作,很有可能会同时读写同一个寄存器。所以在处理器内部,原始的寄存器便被“别名”(aliased) 为内部对软件工程师不可见的寄存器,这样原本在同一个寄存器上执行的操作便可以在临时性的不同的寄存器上执行,无论读写,互不干扰 (注意:这里要求两个操作没有数据依赖)。而对应的微操作的操作数也变为了临时性的别名寄存器,相当于一种空间换时间的策略,并且同时对微指令进行了一次基于别名寄存器的转译。

之后微操作进入 Reorder Buffer。至此,微指令已经准备就绪。它们会被放入 Reservation Station(RS) 并被并行执行。从图中可以看到相当多的执行单元 (Port X)。每一个执行单元都执行一个特定的任务,比如读取 (Load),写入 (Store),整数计算(ALU, SEE)等等。而每一条相关的微指令都可以在它所需要的数据准备好之后执行。这样耗时较长的指令和有数据依赖关系的指令,虽然单从其自身的角度看,并没有任何变化,但它们所带来的阻塞的开销,被后续指令的并行及乱序(提前)执行所分摊,化整为零,带来整体吞吐的提升。

乱序执行核心的神奇之处就在于,它能够最大限度地提升这套机制的效率,并且在外界看来,指令是在顺序执行。这里面的详细细节不在本文的讨论范畴。但乱序执行核心是如此成功,以至于引入该机制的 CPU 即便是在大工作负载的情况下乱序执行核心仍会在大部分时间处于空闲的状态,远未饱和。因此,又引入了另外一个前端 (Front-end, 包括 Fetch 和 Decode) 给该核心输送μ-ops,在系统看来,便可以抽象为两个处理核心,这也就是超线程 (Hyper-thread)N 个物理核心,2N 个逻辑核心的由来。

乱序执行也并不一定 100% 达到顺序执行代码的效果。有些时候确实需要程序员引入内存屏障来确保执行的先后顺序。

但复杂的事物总会引入新的问题,这次矛盾转移到了 Fetch 阶段。如何在面对分支的时候选取正确的路?如果指令选取错误,整条流水线需要首先等待剩余指令执行完毕,清空之后再重新从正确的位置开始。流水线的层次越深,造成的伤害越大。后续的文章,将会介绍一些在编程层面优化的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值