作者:放逐凌晨_690 | 来源:互联网 | 2022-12-07 10:16
我的理解是,在处理器流水线的开头,指令指针(指向要执行的下一条指令的地址)在读取后由分支预测器更新,以便可以在下一个周期获取该新地址.
但是,如果在管道的早期修改指令指针,这是否会影响当前处于执行阶段的指令,这些指令可能依赖于旧的指令指针值?例如,当执行call
当前的EIP需要被推入堆栈时,但是当在分支预测期间更新指令指针时这不会受到影响吗?
1> Peter Cordes..:
您似乎假设只有一个物理EIP寄存器被整个CPU内核使用.
这不起作用,因为每个可能发生异常的指令都需要知道自己的地址.或者当外部中断到来时,CPU可以决定在任何指令之后服务中断,使其成为架构EIP.在长模式(x86-64)中,还存在RIP相对寻址模式,因此call
不是唯一需要当前程序计数器作为数据的指令.
一个简单的流水线CPU可能为每个管道阶段都有一个EIP.
现代超标量无序x86将EIP(或RIP)与每个飞行中的指令(或者每个uop ;相关联;但是多uop指令使其所有uop相互关联,因此指令不能部分退出. )
与架构状态的其他部分(例如EFLAGS,EAX等)不同,该值在解码后是静态已知的.实际上甚至比直接价值更早; 在预解码阶段(或在L1i高速缓存中标记)检测指令边界,以便可以将多个指令并行地馈送到多个解码器.
早期的提取/解码阶段可能只跟踪16字节或32字节提取块的地址,但在解码后我假设内部uop表示中有一个地址字段.对于非分支指令,它可能只是与前一个(节省空间)的小偏移,因此如果需要它可以计算,但我们深入了解实现细节.乱序执行保持了在程序顺序中运行的指令的错觉,并且它们按顺序发出和退出(进入/离开核心的无序执行部分).
相关:x86寄存器:MBR/MDR和指令寄存器基于查看玩具CPU做出了类似的错误假设.没有"当前指令"寄存器保存机器代码字节.有关OoO /流水线CPU的更多信息,请参阅我的答案中的更多链接.
在块被解码之前,分支预测必须工作.即如果我们刚刚在地址abc处获取了一个块,我们需要预测下一个要获取的块.即,预测必须预测将并行解码的16字节指令块中跳跃的存在.
相关:为什么英特尔这些年来改变了静态分支预测机制?