特定向量(未屏蔽)发生硬件中断,CPU检查IF标志并将RFLAGS,CS和RIP推入堆栈,同时后端仍有指令完成,这些指令的分支预测之一是错误的。通常,将清除管道,并且前端开始从正确的地址获取数据,但是在这种情况下,正在进行中断。
When an interrupt occurs, what happens to instructions in the pipeline?
我已经阅读了这篇文章,很明显的解决方案是立即清除管道中的所有内容,以免发生这种情况,然后生成指令以将RFLAGS,CS,RIP推送到TSS中的内核堆栈的位置;但是,问题来了,它如何知道与最新架构状态关联的(CS:)RIP,以便能够将其推入堆栈(假设前端RIP现在位于前面)。这类似于端口0上的被取分支执行单元如何知道(T :)在取假条件错误时应该被取回的内容的(CS:)RIP-指令中的地址以及预测?当您想到陷阱/异常时,会出现相同的问题,CPU需要将当前指令(故障)或下一条指令(陷阱)的地址压入内核堆栈,但是如何计算该指令的地址当它位于流水线的一半位置时,这使我相信必须将地址编码到指令中,并使用长度信息进行计算,这很可能全部在预解码阶段完成。
答案 0 :(得分:3)
在一般情况下,在重新排序缓冲器(ROB)中的每个条目具有被用于存储有关指令地址明确地重建整个指令地址足够信息的字段。在ROB中存储每个指令的整个地址可能太昂贵。对于尚未被分配的指令(即,没有通过管道的分配阶段)时,它们需要至少直到它们到达分配阶段随身携带此信息。
如果同时发生中断和分支预测错误,则处理器可以选择为该中断服务。在这种情况下,需要清除错误路径上的所有指令。处理器还可以选择刷新正确路径上但尚未退出的其他指令。所有这些指令都在ROB和他们的指令地址是已知的。对于每个推测的分支,都有一个标签,用于标识该推测路径上的所有指令,并在该路径上标记所有指令。如果有另一个,后来推测分支,另一个标签被使用,但它也下令相对于以前的标签。使用这些标签,该处理器能够确定到底哪些指令同花顺当任何推测分支的证明是不正确的。这是在分支执行单元中相应的分支指令完成执行之后确定的。分行可以完成执行乱序。计算出msipredicted分支的正确地址后,会将其转发到获取单元和分支预测单元(BPU)。提取单元使用它来从正确的路径中提取指令,而BPU则使用它来更新其预测状态。
该处理器可以选择退役错误预测的分支指令本身和刷新所有其它以后的指令。回收所有重命名寄存器,并保留在退出分支时映射到体系结构寄存器的那些物理寄存器。此时,处理器执行指令以保存当前状态,然后开始获取中断处理程序的指令。
答案 1 :(得分:2)
CPU可能会丢弃ROB的内容,并在服务中断之前回滚到最新的退出状态。
飞行中的机上小姐并没有改变。在中断到达时,由于分支未命中,它可能已经处于回退到退休状态并刷新的过程中,具体取决于CPU(旧的/简单的)。
就像@Hadi所说的那样,CPU可以选择退出该分支(中断将CS:RIP推向正确的分支目标),而不是让它从中断返回后重新执行
但这仅在分支指令已准备好退役的情况下有效:没有比分支还旧的指令仍未执行。由于尽早发现分支未命中很重要,因此我假设分支恢复是在执行过程中发现错误预测时开始的,而不是等到退出后才恢复。 (这与其他类型的错误不同:例如Meltdown和L1TF基于错误的负载 not 不会触发#PF
错误处理,直到其报废,以便CPU确定确实存在是真正的执行路径上的错误。您不希望启动昂贵的管道刷新操作,除非您确定它不会出现错误预测或更早的错误。)
但是由于分支未命中不会引起异常,因此可以在确定分支指令首先是正确路径的一部分之前就开始重定向前端。
例如cmp [cache_miss_load], 123
/ jeq
预测错误,但很长一段时间内不会被发现。然后,在这种错误预测的阴影下,“错误”路径上的cmp eax, 1
/ je
运行,并为此发现了错误预测。通过快速恢复,可以清除掉以前经过的操作并从“正确”路径获取/解码/执行的内容可以在更早发现错误预测之前就开始。
为保持较低的IRQ延迟,CPU不会给飞行中的指令额外的退休时间。同样,任何仍保留其数据在存储缓冲区中的退休存储(尚未提交给L1d)必须在中断处理程序提交任何存储之前进行提交。但是中断正在串行化(我认为),并且处理程序中的任何MMIO或端口IO都可能涉及内存障碍或强排序存储,因此,如果让更多的指令退休,则如果它们涉及存储,则可能会损害IRQ延迟。 (一旦商店退休,即使它的数据仍在商店缓冲区中,它肯定也必须发生)。
无序的后端始终知道如何回退到已知良好的退休状态; ROB的全部内容始终被认为是推测性的,因为任何加载或存储都可能出错,许多其他指令也可能会出错。 1 。猜测分支的分支不是超级特殊。
分支的特殊之处在于具有快速恢复的额外跟踪功能(Nehalem和更新版本中的分支顺序缓冲区),因为预期会在正常操作期间错误地预测频率。有关详细信息,请参见What exactly happens when a skylake CPU mispredicts a branch?。特别是大卫·坎特(David Kanter)的报价:
Nehalem增强了从分支错误预测中恢复的能力,该错误预测已被延续到Sandy Bridge中。一旦发现分支预测错误,内核就可以在知道正确的路径后立即重新开始解码,与此同时无序的机器正在从错误推测的路径中清除错误。以前,直到管道完全刷新后,解码才能恢复。
(此回答有意以英特尔为中心,因为您将其标记为intel,而不是x86。我认为AMD所做的事情类似,并且其他ISA的大多数乱序都是相似的是,除了在内存模型较弱的CPU(允许CPU对负载进行明显重新排序)上,内存顺序错误推测不是问题。
脚注1:div
或任何FPU指令(如果未屏蔽FP异常)也可以。 FP异常结果可能需要微码辅助来处理,即使FP异常像默认情况一样被屏蔽。
在Intel CPU上,内存顺序的错误推测也可能导致流水线(在较早的加载完成之前,推测性地完成了加载,但是在x86内存模型表示加载可能之前,缓存丢失了该行的副本)发挥其价值)。