关于汇编:英特尔:序列化指令和分支预测

Intel: serializing instructions and branch prediction

《英特尔体系结构开发人员手册》(vol3a,第8-26节)指出:

The Pentium processor and more recent processor families use
branch-prediction techniques to improve performance by prefetching the
destination of a branch instruction before the branch instruction is
executed. Consequently, instruction execution is not deterministically
serialized when a branch instruction is executed.

这是什么意思?

听起来真的,真的很糟糕。听起来像是一条串行化指令,比如cpuid中断了分支预测(或者相反),但这似乎不太可能。任何ASM人员都能帮助我理解"非确定性"在这个上下文中的含义吗?

*为了清晰起见而编辑


它的措辞非常混乱,但我相信它的实际含义很简单:"分支不(必然)序列化执行"。我们今天认为这是理所当然的,但事实并非总是如此。


我怀疑你误解了那句话,但我不知道怎么说。在序列化指令和分支预测之间,您看到了什么联系?当它说"指令执行不是确定性序列化"时,它的意思是指令的预取和解码将根据分支预测逻辑来确定,因此它不会每次都以相同的方式工作。但是,这整件事情的重点是使事情更快——如果分支预测是好的,那么大多数时候正确的下一条指令将被获取、解码并准备好执行。


现代超标量处理器通常使指令执行看起来完全具有确定性,并且从CPU外部的角度来看是有序的。在内部,它提前获取指令,投机地执行指令,并以最有效的顺序执行它们。但是任何不应该执行的操作(例如预测失误的分支)都不会被提交,并且内存访问通常在离开CPU之前恢复到正确的顺序。CPU管道的尾部被称为"重新排序缓冲区",因为它的任务是跟踪完成的指令,并且只以程序顺序永久地提交它们的结果。这对于正确的程序行为很重要,尤其是在出现分支预测失误和异常的情况下;如果发生异常(例如除以零),则后续指令可能已被解码并执行,在将异常移交给操作系统之前,必须从ROB中清除这些指令,并正确重置程序计数器。

关于内存排序,程序排序的假象有一些例外,其中读可以任意重新排序,读和写之间可以有一些(可能是推测性的)重新排序,但只有在与内存映射的I/O硬件交谈时才关心这一点。有一些指令可以确保特定的顺序,CPU对于访问未缓存内存的顺序非常小心,因为这意味着它是I/O。


预测失误的分支是序列化指令,而预测正确的分支则不是。

因为在执行分支之前,您不知道它的预测是否正确,所以您不能预先知道它是否会序列化指令流。这种行为是不确定性的,因为它依赖于分支预测。

您可以在条件分支之前和之后构造一个带有内存访问的角盒,其中代码的行为取决于分支的预测是否正确。(即分支是否序列化。)