Intel架构开发人员手册(Vol3A, Section 8-26)说:
奔腾处理器和最新的处理器系列使用分支预测技术,通过预取在分支指令之前的分支指令的目的地执行。因此,指令的执行是不确定的执行分支指令时序列化。
这是什么意思?
听起来真的,真的很糟糕。这听起来像是像CPUID这样的序列化指令破坏了分支预测(反之亦然),但这似乎不太可能。有ASM的人能帮我理解在这种情况下"不确定性"是什么意思吗?
*编辑清晰
这是非常令人困惑的措辞,但我相信它的实际含义很简单:"分支(不一定)序列化执行"。今天我们认为这是理所当然的,但过去并非如此。
我怀疑你误解了这句话,但我不能确切地说出来。您认为序列化指令和分支预测之间有什么联系?当它说"指令执行不确定性序列化"时,它的意思是指令的预取和解码将根据分支预测逻辑确定,因此它不会每次都以相同的方式工作。但是整个事情的重点是使事情更快——如果分支预测是好的,大多数情况下,正确的下一个指令将被提取、解码并准备好运行。
错误预测的分支是序列化指令,正确预测的分支不是。
因为在执行之前你不知道分支预测是否正确,所以你不能事先知道它是否会序列化指令流。该行为是不确定的,因为它取决于分支预测。
您可能会在条件分支之前和之后构建内存访问的角落情况,其中代码的行为取决于分支是否被正确预测。(即分支是否序列化)
从CPU外部的角度来看,现代超标量处理器通常使指令执行看起来是完全确定的和有序的。在内部,它提前获取指令,推测地执行指令,并以最有效的顺序执行它们。但是任何不应该被执行的(例如,错误预测的分支)都不会被提交,并且内存访问通常在离开CPU之前被放回正确的顺序。CPU管道的尾部被称为"重排序缓冲区",因为它的工作是跟踪完成的指令,并且只按程序顺序永久提交它们的结果。这对于正确的程序行为非常重要,特别是在面对分支错误预测和异常等情况时;如果发生异常(例如除以0),后续指令可能已经被解码并执行,在将异常交给操作系统之前,必须从ROB中清除这些指令并正确地重置程序计数器。
关于内存排序,有一些例外的程序排序错觉,其中读可以被任意重排序,并且在读和写之间可以有一些(可能是推测的)重排序,但是您只在与内存映射的I/O硬件交谈时才关心这一点。有一些指令确保特定的顺序,cpu对非缓存内存访问的顺序非常小心,因为这被认为意味着它是I/o。